CDN Cache: - Migrate from nginx to Squid proxy for better caching - Add aggressive caching rules for Windows Update, Linux repos, Steam, Apple - Proper firewall integration via UCI (transparent proxy) - Real-time stats from Squid access logs Network Modes: - Complete UI rework with MirrorBox dark theme - 9 network modes with emojis and descriptions - Dynamic CSS animations and modern styling Fixes: - Fix jshn boolean handling in secubox-recovery (1/0 vs true/false) - Fix nDPId RPCD to use netifyd as fallback DPI provider - Update media-flow and security-threats dashboards Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
249 lines
7.6 KiB
JavaScript
249 lines
7.6 KiB
JavaScript
'use strict';
|
|
'require baseclass';
|
|
'require rpc';
|
|
|
|
var callStatus = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'status',
|
|
expect: { }
|
|
});
|
|
|
|
var callGetActiveStreams = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_active_streams',
|
|
expect: { }
|
|
});
|
|
|
|
var callGetStreamHistory = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_stream_history',
|
|
params: ['hours'],
|
|
expect: { history: [] }
|
|
});
|
|
|
|
var callGetStatsByService = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_stats_by_service',
|
|
expect: { services: {} }
|
|
});
|
|
|
|
var callGetStatsByClient = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_stats_by_client',
|
|
expect: { clients: {} }
|
|
});
|
|
|
|
var callGetServiceDetails = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_service_details',
|
|
params: ['service'],
|
|
expect: { }
|
|
});
|
|
|
|
var callSetAlert = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'set_alert',
|
|
params: ['service', 'threshold_hours', 'action'],
|
|
expect: { }
|
|
});
|
|
|
|
var callDeleteAlert = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'delete_alert',
|
|
params: ['alert_id'],
|
|
expect: { }
|
|
});
|
|
|
|
var callListAlerts = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'list_alerts',
|
|
expect: { alerts: [] }
|
|
});
|
|
|
|
var callClearHistory = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'clear_history',
|
|
expect: { }
|
|
});
|
|
|
|
var callGetSettings = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'get_settings',
|
|
expect: { }
|
|
});
|
|
|
|
var callSetSettings = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'set_settings',
|
|
params: ['enabled', 'history_retention', 'refresh_interval'],
|
|
expect: { }
|
|
});
|
|
|
|
var callStartNdpid = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'start_ndpid',
|
|
expect: { success: false }
|
|
});
|
|
|
|
var callStopNdpid = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'stop_ndpid',
|
|
expect: { success: false }
|
|
});
|
|
|
|
var callStartNetifyd = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'start_netifyd',
|
|
expect: { success: false }
|
|
});
|
|
|
|
var callStopNetifyd = rpc.declare({
|
|
object: 'luci.media-flow',
|
|
method: 'stop_netifyd',
|
|
expect: { success: false }
|
|
});
|
|
|
|
// nDPId Integration
|
|
var callNdpidStatus = rpc.declare({
|
|
object: 'luci.ndpid',
|
|
method: 'get_service_status',
|
|
expect: { }
|
|
});
|
|
|
|
var callNdpidFlows = rpc.declare({
|
|
object: 'luci.ndpid',
|
|
method: 'get_detailed_flows',
|
|
expect: { flows: [] }
|
|
});
|
|
|
|
var callNdpidTopApps = rpc.declare({
|
|
object: 'luci.ndpid',
|
|
method: 'get_top_applications',
|
|
expect: { applications: [] }
|
|
});
|
|
|
|
var callNdpidCategories = rpc.declare({
|
|
object: 'luci.ndpid',
|
|
method: 'get_categories',
|
|
expect: { categories: [] }
|
|
});
|
|
|
|
// Streaming service definitions
|
|
var streamingServices = {
|
|
'Netflix': { icon: '🎬', color: '#e50914', category: 'video' },
|
|
'YouTube': { icon: '▶️', color: '#ff0000', category: 'video' },
|
|
'Disney': { icon: '🏰', color: '#113ccf', category: 'video' },
|
|
'Amazon Prime': { icon: '📦', color: '#00a8e1', category: 'video' },
|
|
'HBO': { icon: '🎭', color: '#5822b4', category: 'video' },
|
|
'Hulu': { icon: '📺', color: '#1ce783', category: 'video' },
|
|
'AppleTV': { icon: '🍎', color: '#555555', category: 'video' },
|
|
'Twitch': { icon: '🎮', color: '#9146ff', category: 'gaming' },
|
|
'Spotify': { icon: '🎵', color: '#1db954', category: 'audio' },
|
|
'Apple Music': { icon: '🎧', color: '#fa243c', category: 'audio' },
|
|
'Tidal': { icon: '🌊', color: '#000000', category: 'audio' },
|
|
'Deezer': { icon: '🎶', color: '#feaa2d', category: 'audio' },
|
|
'SoundCloud': { icon: '☁️', color: '#ff5500', category: 'audio' },
|
|
'TikTok': { icon: '📱', color: '#000000', category: 'social' },
|
|
'Instagram': { icon: '📷', color: '#e4405f', category: 'social' },
|
|
'Facebook': { icon: '👤', color: '#1877f2', category: 'social' },
|
|
'Discord': { icon: '💬', color: '#5865f2', category: 'gaming' },
|
|
'Steam': { icon: '🎮', color: '#1b2838', category: 'gaming' },
|
|
'Xbox': { icon: '🎯', color: '#107c10', category: 'gaming' },
|
|
'PlayStation': { icon: '🎲', color: '#003791', category: 'gaming' },
|
|
'Zoom': { icon: '📹', color: '#2d8cff', category: 'conferencing' },
|
|
'Teams': { icon: '👥', color: '#6264a7', category: 'conferencing' },
|
|
'WebRTC': { icon: '🔗', color: '#333333', category: 'conferencing' }
|
|
};
|
|
|
|
// Quality detection based on bandwidth
|
|
function detectQuality(bytesPerSec) {
|
|
if (bytesPerSec > 2500000) return { label: '4K', color: '#9333ea', icon: '🎬' };
|
|
if (bytesPerSec > 625000) return { label: 'FHD', color: '#2563eb', icon: '📺' };
|
|
if (bytesPerSec > 312500) return { label: 'HD', color: '#059669', icon: '📹' };
|
|
return { label: 'SD', color: '#d97706', icon: '📱' };
|
|
}
|
|
|
|
// Get streaming service info
|
|
function getServiceInfo(appName) {
|
|
if (!appName) return { icon: '📡', color: '#6b7280', category: 'unknown' };
|
|
for (var name in streamingServices) {
|
|
if (appName.toLowerCase().indexOf(name.toLowerCase()) !== -1) {
|
|
return { name: name, ...streamingServices[name] };
|
|
}
|
|
}
|
|
return { icon: '📡', color: '#6b7280', category: 'other', name: appName };
|
|
}
|
|
|
|
// Device type detection for media
|
|
var mediaDeviceTypes = {
|
|
'smart_tv': { icon: '📺', label: 'Smart TV', apps: ['Netflix', 'YouTube', 'Disney', 'AppleTV', 'Prime'] },
|
|
'gaming': { icon: '🎮', label: 'Gaming', apps: ['Steam', 'PlayStation', 'Xbox', 'Twitch', 'Discord'] },
|
|
'mobile': { icon: '📱', label: 'Mobile', apps: ['TikTok', 'Instagram', 'Spotify'] },
|
|
'speaker': { icon: '🔊', label: 'Smart Speaker', apps: ['Spotify', 'Apple Music', 'Amazon'] },
|
|
'computer': { icon: '💻', label: 'Computer', apps: ['Zoom', 'Teams', 'Chrome', 'Firefox'] }
|
|
};
|
|
|
|
function classifyMediaDevice(apps) {
|
|
if (!apps || !Array.isArray(apps)) return { type: 'unknown', icon: '📟', label: 'Unknown' };
|
|
for (var type in mediaDeviceTypes) {
|
|
var typeApps = mediaDeviceTypes[type].apps;
|
|
for (var i = 0; i < apps.length; i++) {
|
|
for (var j = 0; j < typeApps.length; j++) {
|
|
if (apps[i].toLowerCase().indexOf(typeApps[j].toLowerCase()) !== -1) {
|
|
return { type: type, ...mediaDeviceTypes[type] };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return { type: 'unknown', icon: '📟', label: 'Unknown' };
|
|
}
|
|
|
|
// QoS priority suggestions
|
|
var qosPriorities = {
|
|
'video': { priority: 'high', dscp: 'AF41', desc: 'Video streaming - prioritize for smooth playback' },
|
|
'audio': { priority: 'medium-high', dscp: 'AF31', desc: 'Audio streaming - moderate priority' },
|
|
'gaming': { priority: 'highest', dscp: 'EF', desc: 'Gaming - lowest latency required' },
|
|
'conferencing': { priority: 'highest', dscp: 'EF', desc: 'Video calls - real-time priority' },
|
|
'social': { priority: 'low', dscp: 'BE', desc: 'Social media - best effort' },
|
|
'other': { priority: 'normal', dscp: 'BE', desc: 'Standard priority' }
|
|
};
|
|
|
|
function getQosSuggestion(category) {
|
|
return qosPriorities[category] || qosPriorities.other;
|
|
}
|
|
|
|
return baseclass.extend({
|
|
// Core methods
|
|
getStatus: callStatus,
|
|
getActiveStreams: callGetActiveStreams,
|
|
getStreamHistory: callGetStreamHistory,
|
|
getStatsByService: callGetStatsByService,
|
|
getStatsByClient: callGetStatsByClient,
|
|
getServiceDetails: callGetServiceDetails,
|
|
setAlert: callSetAlert,
|
|
deleteAlert: callDeleteAlert,
|
|
listAlerts: callListAlerts,
|
|
clearHistory: callClearHistory,
|
|
getSettings: callGetSettings,
|
|
setSettings: callSetSettings,
|
|
startNdpid: callStartNdpid,
|
|
stopNdpid: callStopNdpid,
|
|
startNetifyd: callStartNetifyd,
|
|
stopNetifyd: callStopNetifyd,
|
|
|
|
// nDPId methods
|
|
getNdpidStatus: callNdpidStatus,
|
|
getNdpidFlows: callNdpidFlows,
|
|
getNdpidTopApps: callNdpidTopApps,
|
|
getNdpidCategories: callNdpidCategories,
|
|
|
|
// Utility functions
|
|
streamingServices: streamingServices,
|
|
mediaDeviceTypes: mediaDeviceTypes,
|
|
qosPriorities: qosPriorities,
|
|
detectQuality: detectQuality,
|
|
getServiceInfo: getServiceInfo,
|
|
classifyMediaDevice: classifyMediaDevice,
|
|
getQosSuggestion: getQosSuggestion
|
|
});
|