parent
20752782f7
commit
07dd54a336
|
@ -1,13 +0,0 @@
|
|||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
|
@ -1,46 +0,0 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events*.json
|
||||
speed-measure-plugin*.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"speedtest": {
|
||||
"projectType": "library",
|
||||
"root": "projects/speedtest",
|
||||
"sourceRoot": "projects/speedtest/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/speedtest/tsconfig.lib.json",
|
||||
"project": "projects/speedtest/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/speedtest/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/speedtest/src/test.ts",
|
||||
"tsConfig": "projects/speedtest/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/speedtest/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/speedtest/tsconfig.lib.json",
|
||||
"projects/speedtest/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
"defaultProject": "speedtest"
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
MODULENAME=$(basename $PWD)
|
||||
|
||||
check_workspace() {
|
||||
if [[ ! -d "node_modules" ]]; then
|
||||
while true; do
|
||||
read -p "[!!] The Angular workspace has not been prepared. Would you like to do it now? [Y\n] " yn
|
||||
case $yn in
|
||||
[Yy]* ) prepare_workspace; break;;
|
||||
[Nn]* ) exit 1;;
|
||||
* ) prepare_workspace; break;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_workspace() {
|
||||
echo "[*] Preparing the Angular workspace."
|
||||
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "[!] NPM does not appear to be installed on this system. Failed to create workspace."
|
||||
return
|
||||
fi
|
||||
|
||||
if ! npm install &> /dev/null; then
|
||||
echo "[!] Failed to prepare workspace. Run npm install to see why."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[*] Prepared the Angular workspace successfully."
|
||||
}
|
||||
|
||||
build_module() {
|
||||
./node_modules/@angular/cli/bin/ng build --prod > /dev/null 2>&1
|
||||
RET=$?
|
||||
|
||||
if [[ $RET -ne 0 ]]; then
|
||||
echo "[!] Angular Build Failed: Run 'ng build --prod' to figure out why."
|
||||
exit 1
|
||||
else
|
||||
echo "[*] Angular Build Succeeded"
|
||||
fi
|
||||
|
||||
# Step 2: Copy the required files to the build output
|
||||
cp -r projects/$MODULENAME/src/module.svg dist/$MODULENAME/bundles/
|
||||
cp -r projects/$MODULENAME/src/module.json dist/$MODULENAME/bundles/
|
||||
cp -r projects/$MODULENAME/src/module.py dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
cp -r projects/$MODULENAME/src/module.php dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
cp -r projects/$MODULENAME/src/assets/ dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
|
||||
# Step 3: Clean up
|
||||
rm -rf dist/$MODULENAME/bundles/*.map
|
||||
rm -rf dist/$MODULENAME/bundles/*.min*
|
||||
rm -rf bundletmp
|
||||
mv dist/$MODULENAME/bundles/ bundletmp
|
||||
rm -rf dist/$MODULENAME/*
|
||||
mv bundletmp/* dist/$MODULENAME/
|
||||
rm -rf bundletmp
|
||||
}
|
||||
|
||||
package() {
|
||||
VERS=$(cat dist/$MODULENAME/module.json | grep "version" | awk '{split($0, a, ": "); gsub("\"", "", a[2]); gsub(",", "", a[2]); print a[2]}')
|
||||
rm -rf $MODULENAME-$VERS.tar.gz
|
||||
echo "[*] Packaging $MODULENAME (Version $VERS)"
|
||||
cd dist/
|
||||
tar -pczf $MODULENAME-$VERS.tar.gz $MODULENAME
|
||||
mv $MODULENAME-$VERS.tar.gz ../
|
||||
cd ../
|
||||
}
|
||||
|
||||
copy_to_device() {
|
||||
echo "[*] Copying module to WiFi Pineapple via SCP"
|
||||
scp -r dist/$MODULENAME root@172.16.42.1:/pineapple/modules
|
||||
}
|
||||
|
||||
main() {
|
||||
check_workspace
|
||||
build_module
|
||||
|
||||
if [[ $1 == "package" ]]; then
|
||||
package
|
||||
elif [[ $1 == "copy" ]]; then
|
||||
copy_to_device
|
||||
fi
|
||||
|
||||
echo "[*] Success!"
|
||||
}
|
||||
|
||||
main $1
|
File diff suppressed because it is too large
Load Diff
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"name": "speedtest",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~9.1.11",
|
||||
"@angular/cdk": "^9.2.4",
|
||||
"@angular/common": "~9.1.11",
|
||||
"@angular/compiler": "~9.1.11",
|
||||
"@angular/core": "~9.1.11",
|
||||
"@angular/flex-layout": "^9.0.0-beta.31",
|
||||
"@angular/forms": "~9.1.11",
|
||||
"@angular/material": "^9.2.4",
|
||||
"@angular/platform-browser": "~9.1.11",
|
||||
"@angular/platform-browser-dynamic": "~9.1.11",
|
||||
"@angular/router": "~9.1.11",
|
||||
"rxjs": "~6.5.5",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.901.8",
|
||||
"@angular-devkit/build-ng-packagr": "~0.901.8",
|
||||
"@angular/cli": "~9.1.8",
|
||||
"@angular/compiler-cli": "~9.1.11",
|
||||
"@angular/language-service": "~9.1.11",
|
||||
"@types/jasmine": "~3.5.10",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^5.1.2",
|
||||
"jasmine-core": "~3.5.0",
|
||||
"jasmine-spec-reporter": "~5.0.2",
|
||||
"karma": "~5.1.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
"karma-jasmine": "~3.3.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.0",
|
||||
"ng-packagr": "^9.1.5",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.10.2",
|
||||
"tslint": "~6.1.2",
|
||||
"typescript": "^3.6.5"
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/speedtest",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"name": "speedtest",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "ng build --prod"
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
This file is a placeholder for module assets that you may like to add.
|
|
@ -1,63 +0,0 @@
|
|||
<mat-card>
|
||||
|
||||
<mat-card-header>
|
||||
|
||||
<mat-card-title>SpeedTest Module</mat-card-title>
|
||||
|
||||
<mat-card-subtitle>Test the speed of the internet connection</mat-card-subtitle>
|
||||
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<u>Network</u>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Interface</b> : {{ network_interface }}
|
||||
</li>
|
||||
<li>
|
||||
<b>Connected</b> : {{ (network_connected) ? 'OK' : 'You are not connected to the Internet' }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div *ngIf="network_status">
|
||||
<p>
|
||||
<u>Dependencies</u>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>python3-pip</b> : {{ (dependency_python3_pip) ? 'OK' : 'Dependency is not installed' }}
|
||||
</li>
|
||||
<li>
|
||||
<b>speedtest-cli</b> : {{ (dependency_speedtest_cli) ? 'OK' : 'Dependency is not installed' }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<button *ngIf="!dependency_python3_pip || !dependency_speedtest_cli" mat-flat-button color="warn" (click)="install_dependencies();">
|
||||
<span *ngIf="dependencies_status">Install dependencies</span>
|
||||
<span *ngIf="!dependencies_status">
|
||||
<mat-spinner [diameter]="24"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="network_status && dependency_python3_pip && dependency_speedtest_cli">
|
||||
<button mat-flat-button color="accent" (click)="start_speedtest();">
|
||||
<span *ngIf="speedtest_status">Start SpeedTest</span>
|
||||
<span *ngIf="!speedtest_status">
|
||||
<mat-spinner [diameter]="24"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<pre>{{ speedtest_output }}</pre>
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
|
@ -1,124 +0,0 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-speedtest',
|
||||
templateUrl: './speedtest.component.html',
|
||||
styleUrls: ['./speedtest.component.css']
|
||||
})
|
||||
export class speedtestComponent implements OnInit {
|
||||
|
||||
constructor(private API: ApiService) { }
|
||||
|
||||
poll_interval = null;
|
||||
poll_job(action: string, job_id: string): void {
|
||||
this.poll_interval = setInterval(
|
||||
() => {
|
||||
this.API.request(
|
||||
{
|
||||
module: 'speedtest',
|
||||
action: action,
|
||||
job_id: job_id
|
||||
},
|
||||
(response) => {
|
||||
if (response.is_complete) {
|
||||
if (action === 'poll_dependencies') {
|
||||
this.check_dependencies();
|
||||
} else if (action === 'poll_speedtest') {
|
||||
this.speedtest_status = !this.speedtest_status;
|
||||
this.output_speedtest();
|
||||
}
|
||||
clearInterval(this.poll_interval);
|
||||
}
|
||||
}
|
||||
)
|
||||
}, 5000
|
||||
)
|
||||
}
|
||||
|
||||
network_interface : string = null;
|
||||
network_connected : boolean = null;
|
||||
network_status : boolean = false;
|
||||
check_network(): void {
|
||||
this.API.APIGet(
|
||||
'/api/settings/networking/clientmode/status',
|
||||
(response) => {
|
||||
this.network_interface = response.interfaces[0];
|
||||
this.network_connected = response.connected;
|
||||
if (response.connected) {
|
||||
this.network_status = !this.network_status;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
dependency_python3_pip : boolean = null;
|
||||
dependency_speedtest_cli : boolean = null;
|
||||
check_dependencies(): void {
|
||||
this.API.request(
|
||||
{
|
||||
module: 'speedtest',
|
||||
action: 'check_dependencies'
|
||||
},
|
||||
(response) => {
|
||||
this.dependency_python3_pip = response.dependency_python3_pip;
|
||||
this.dependency_speedtest_cli = response.dependency_speedtest_cli;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
dependencies_status : boolean = true;
|
||||
install_dependencies(): void {
|
||||
this.dependencies_status = !this.dependencies_status;
|
||||
this.API.request(
|
||||
{
|
||||
module: 'speedtest',
|
||||
action: 'install_dependencies'
|
||||
},
|
||||
(response) => {
|
||||
this.poll_job('poll_dependencies', response.job_id);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
speedtest_status : boolean = true;
|
||||
output_file: string = null;
|
||||
start_speedtest(): void {
|
||||
this.speedtest_status = !this.speedtest_status;
|
||||
this.speedtest_output = null;
|
||||
this.API.request(
|
||||
{
|
||||
module: 'speedtest',
|
||||
action: 'start_speedtest'
|
||||
},
|
||||
(response) => {
|
||||
this.output_file = response.output_file;
|
||||
this.poll_job('poll_speedtest', response.job_id)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
speedtest_output : string = null;
|
||||
output_speedtest(): void {
|
||||
this.API.request(
|
||||
{
|
||||
module: 'speedtest',
|
||||
action: 'output_speedtest',
|
||||
output_file: this.output_file
|
||||
},
|
||||
(response) => {
|
||||
this.speedtest_output = response.speedtest_output;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.check_network();
|
||||
this.check_dependencies();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
clearInterval(this.poll_interval);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Hak5 LLC.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { BidiModule } from '@angular/cdk/bidi';
|
||||
import { ObserversModule } from '@angular/cdk/observers';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { PlatformModule } from '@angular/cdk/platform';
|
||||
import { PortalModule } from '@angular/cdk/portal';
|
||||
import { CdkStepperModule } from '@angular/cdk/stepper';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { CdkTreeModule } from '@angular/cdk/tree';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatGridListModule } from '@angular/material/grid-list';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatSliderModule } from '@angular/material/slider';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatTreeModule } from '@angular/material/tree';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule],
|
||||
exports: [
|
||||
// CDK
|
||||
A11yModule,
|
||||
BidiModule,
|
||||
ObserversModule,
|
||||
OverlayModule,
|
||||
PlatformModule,
|
||||
PortalModule,
|
||||
CdkStepperModule,
|
||||
CdkTableModule,
|
||||
CdkTreeModule,
|
||||
|
||||
// Material
|
||||
MatAutocompleteModule,
|
||||
MatBadgeModule,
|
||||
MatBottomSheetModule,
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatChipsModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatGridListModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatNativeDateModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatSliderModule,
|
||||
MatSlideToggleModule,
|
||||
MatSnackBarModule,
|
||||
MatSortModule,
|
||||
MatStepperModule,
|
||||
MatTableModule,
|
||||
MatTabsModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatTreeModule,
|
||||
],
|
||||
declarations: []
|
||||
})
|
||||
export class MaterialModule {
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ApiService {
|
||||
public static totalRequests = 0;
|
||||
apiModuleBusy = document.getElementById('ApiModuleBusy');
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private router: Router) {}
|
||||
|
||||
emptyResponse = {error: 'Request returned empty response'};
|
||||
|
||||
unauth(): void {
|
||||
localStorage.removeItem('authToken');
|
||||
|
||||
if (this.router.url !== '/Login' && this.router.url !== '/Setup') {
|
||||
this.router.navigateByUrl('/Login');
|
||||
}
|
||||
}
|
||||
|
||||
setBusy(): void {
|
||||
this.apiModuleBusy.style.display = 'block';
|
||||
}
|
||||
setNotBusy(): void {
|
||||
this.apiModuleBusy.style.display = 'none';
|
||||
}
|
||||
|
||||
request(payload: any, callback: (any) => void) {
|
||||
this.setBusy();
|
||||
let resp;
|
||||
|
||||
this.http.post('/api/module/request', payload).subscribe((r: any) => {
|
||||
if (r === undefined || r === null) {
|
||||
resp = this.emptyResponse;
|
||||
} else if (r.error) {
|
||||
resp = r;
|
||||
} else {
|
||||
resp = r.payload;
|
||||
}
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
this.setNotBusy();
|
||||
callback(resp);
|
||||
}, () => {
|
||||
this.setNotBusy();
|
||||
callback(resp);
|
||||
});
|
||||
|
||||
ApiService.totalRequests++;
|
||||
}
|
||||
|
||||
APIGet(path: string, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.get(path).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIGetAsync(path: string): Promise<any> {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
return await this.http.get(path).toPromise();
|
||||
}
|
||||
|
||||
APIPut(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.put(path, body).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIPutAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.put(path, body).toPromise();
|
||||
}
|
||||
|
||||
APIPost(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.post(path, body).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
resp = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIPostAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.post(path, body).toPromise();
|
||||
}
|
||||
|
||||
APIDelete(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
const opts = {
|
||||
headers: null,
|
||||
body: body
|
||||
};
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.delete(path, opts).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIDeleteAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.delete(path, body).toPromise();
|
||||
}
|
||||
|
||||
APIDownload(fullpath: string, filename: string): void {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
const body = {
|
||||
filename: fullpath
|
||||
};
|
||||
|
||||
this.http.post('/api/download', body, {responseType: 'blob'}).subscribe((r) => {
|
||||
const url = window.URL.createObjectURL(r);
|
||||
const a = document.createElement('a');
|
||||
document.body.appendChild(a);
|
||||
a.setAttribute('style', 'display: none');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
a.remove();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class speedtestService {
|
||||
constructor() {}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { speedtestComponent } from './components/speedtest.component';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import {MaterialModule} from './modules/material/material.module';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: speedtestComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [speedtestComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild(routes),
|
||||
MaterialModule,
|
||||
FlexLayoutModule,
|
||||
FormsModule,
|
||||
],
|
||||
exports: [speedtestComponent]
|
||||
})
|
||||
export class speedtestModule { }
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"name": "speedtest",
|
||||
"title": "SpeedTest",
|
||||
"description": "Test Internet Speed",
|
||||
"version": "1.1",
|
||||
"author": "TW-D",
|
||||
"firmware_required": "1.0.0"
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
import pineapple.helpers.opkg_helpers as opkg
|
||||
import pineapple.helpers.notification_helpers as notifier
|
||||
|
||||
from datetime import datetime
|
||||
from pineapple.jobs import Job, JobManager
|
||||
from pineapple.modules import Module, Request
|
||||
from pineapple.helpers.opkg_helpers import OpkgJob
|
||||
|
||||
# CONSTANTS
|
||||
|
||||
_LOGGING = logging.DEBUG
|
||||
|
||||
_OPKG_INSTALL_PYTHON3_PIP = 'python3-pip'
|
||||
|
||||
_PIP3_COMMAND = '/usr/bin/pip3'
|
||||
_PIP3_INSTALL_ARGUMENT = 'install'
|
||||
_PIP3_PACKAGE_ARGUMENT = 'speedtest-cli'
|
||||
|
||||
_SPEED_TEST_CLI_COMMAND = '/usr/bin/speedtest-cli'
|
||||
_SPEED_TEST_CLI_ARGUMENT = '--no-pre-allocate'
|
||||
_SPEED_TEST_CLI_COMMAND_PATHLIB = pathlib.Path(_SPEED_TEST_CLI_COMMAND)
|
||||
|
||||
_SPEED_TEST_CLI_OUTPUT_DIRECTORY = '/tmp/speedtest-cli'
|
||||
_SPEED_TEST_CLI_OUTPUT_DIRECTORY_PATHLIB = pathlib.Path(_SPEED_TEST_CLI_OUTPUT_DIRECTORY)
|
||||
|
||||
_SPEED_TEST_CLI_OUTPUT_FILENAME = f"{datetime.now().strftime('%Y-%m-%dT%H-%M-%S')}.txt"
|
||||
_SPEED_TEST_CLI_OUTPUT_PATH = f"{_SPEED_TEST_CLI_OUTPUT_DIRECTORY}/{_SPEED_TEST_CLI_OUTPUT_FILENAME}"
|
||||
|
||||
# OBJECTS
|
||||
|
||||
module = Module('speedtest', _LOGGING)
|
||||
|
||||
job_manager = JobManager(
|
||||
name='speedtest',
|
||||
module=module,
|
||||
log_level=_LOGGING
|
||||
)
|
||||
|
||||
# CLASSES
|
||||
|
||||
class SpeedTestCliInstallJob(Job[bool]):
|
||||
|
||||
def __init__(self, command: str, install_argument: str, package_argument: str):
|
||||
super().__init__()
|
||||
self.command = command
|
||||
self.install_argument = install_argument
|
||||
self.package_argument = package_argument
|
||||
|
||||
def do_work(self, logger: logging.Logger) -> bool:
|
||||
subprocess.call([self.command, self.install_argument, self.package_argument])
|
||||
return True
|
||||
|
||||
class SpeedTestJob(Job[bool]):
|
||||
|
||||
def __init__(self, command: str, argument: str, output_path: str):
|
||||
super().__init__()
|
||||
self.command = command
|
||||
self.argument = argument
|
||||
self.output_path = output_path
|
||||
|
||||
def do_work(self, logger: logging.Logger) -> bool:
|
||||
output = open(self.output_path, 'w')
|
||||
subprocess.call([self.command, self.argument], stdout=output, stderr=output)
|
||||
return True
|
||||
|
||||
# EVENTS
|
||||
|
||||
@module.on_start()
|
||||
def create_output_directory():
|
||||
if not _SPEED_TEST_CLI_OUTPUT_DIRECTORY_PATHLIB.exists():
|
||||
_SPEED_TEST_CLI_OUTPUT_DIRECTORY_PATHLIB.mkdir(parents=True)
|
||||
module.logger.debug('[+] speedtest-module : Output directory created')
|
||||
|
||||
@module.on_shutdown()
|
||||
def delete_output_directory():
|
||||
for item in _SPEED_TEST_CLI_OUTPUT_DIRECTORY_PATHLIB.iterdir():
|
||||
if item.is_file():
|
||||
item.unlink()
|
||||
module.logger.debug('[+] speedtest-module : Output directory cleared')
|
||||
|
||||
# EXTRAS
|
||||
|
||||
def follow_with_the_installation_of_speedtest_cli(job: OpkgJob):
|
||||
if job.install and job.was_successful:
|
||||
module.logger.debug('[+] speedtest-module : python3-pip installed')
|
||||
job_manager.execute_job(SpeedTestCliInstallJob(_PIP3_COMMAND, _PIP3_INSTALL_ARGUMENT, _PIP3_PACKAGE_ARGUMENT), callbacks=[ notify_dependencies_installed ])
|
||||
|
||||
|
||||
# NOTIFICATIONS
|
||||
|
||||
def notify_dependencies_installed(job: SpeedTestCliInstallJob):
|
||||
if not job.was_successful:
|
||||
module.send_notification(job.error, notifier.ERROR)
|
||||
else:
|
||||
module.send_notification('python3-pip and speedtest-cli installed', notifier.INFO)
|
||||
|
||||
def notify_speedtest_completed(job: SpeedTestJob):
|
||||
if not job.was_successful:
|
||||
module.send_notification(job.error, notifier.ERROR)
|
||||
else:
|
||||
module.send_notification('SpeedTest completed', notifier.INFO)
|
||||
|
||||
|
||||
# HANDLES
|
||||
|
||||
@module.handles_action('check_dependencies')
|
||||
def check_dependencies(request: Request):
|
||||
module.logger.debug('[+] speedtest-module : Check required dependencies')
|
||||
python3_pip_installed = opkg.check_if_installed(_OPKG_INSTALL_PYTHON3_PIP, module.logger)
|
||||
speedtest_cli_installed = _SPEED_TEST_CLI_COMMAND_PATHLIB.exists()
|
||||
return {
|
||||
'dependency_python3_pip': python3_pip_installed,
|
||||
'dependency_speedtest_cli': speedtest_cli_installed
|
||||
}
|
||||
|
||||
@module.handles_action('install_dependencies')
|
||||
def install_dependencies(request: Request):
|
||||
module.logger.debug('[+] speedtest-module : Install required dependencies')
|
||||
job_id = job_manager.execute_job(OpkgJob(_OPKG_INSTALL_PYTHON3_PIP, True), callbacks=[ follow_with_the_installation_of_speedtest_cli ])
|
||||
return {
|
||||
'job_id': job_id
|
||||
}
|
||||
|
||||
# Duplicate code :(
|
||||
@module.handles_action('poll_dependencies')
|
||||
def poll_dependencies(request: Request):
|
||||
job_id = request.job_id
|
||||
is_complete = False
|
||||
if len(job_manager.jobs) >= 1:
|
||||
for job, runner in job_manager.jobs.items():
|
||||
if job == job_id and runner.job.is_complete:
|
||||
is_complete = True
|
||||
break
|
||||
return {
|
||||
'is_complete': is_complete
|
||||
}
|
||||
|
||||
@module.handles_action('start_speedtest')
|
||||
def start_speedtest(request: Request):
|
||||
job_id = job_manager.execute_job(SpeedTestJob(_SPEED_TEST_CLI_COMMAND, _SPEED_TEST_CLI_ARGUMENT, _SPEED_TEST_CLI_OUTPUT_PATH), callbacks=[ notify_speedtest_completed ])
|
||||
return {
|
||||
'job_id': job_id,
|
||||
'output_file': _SPEED_TEST_CLI_OUTPUT_PATH
|
||||
}
|
||||
|
||||
@module.handles_action('poll_speedtest')
|
||||
def poll_speedtest(request: Request):
|
||||
job_id = request.job_id
|
||||
is_complete = False
|
||||
if len(job_manager.jobs) >= 1:
|
||||
for job, runner in job_manager.jobs.items():
|
||||
if job == job_id and runner.job.is_complete:
|
||||
is_complete = True
|
||||
break
|
||||
return {
|
||||
'is_complete': is_complete
|
||||
}
|
||||
|
||||
|
||||
@module.handles_action('output_speedtest')
|
||||
def output_speedtest(request: Request):
|
||||
output_file = request.output_file;
|
||||
with open(output_file, 'r') as reader:
|
||||
return {
|
||||
'speedtest_output': reader.read()
|
||||
}
|
||||
|
||||
if __name__ == '__main__':
|
||||
module.start()
|
|
@ -1,75 +0,0 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 35.933 35.933" style="enable-background:new 0 0 35.933 35.933;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M29.646,10.461c-3.14-2.693-7.215-4.331-11.682-4.331C8.043,6.13,0,14.173,0,24.099c0,0.266,0.026,2.75,0.038,3.015v2.69
|
||||
H35.86V27.31l0.034-0.196c0.011-0.266,0.039-2.749,0.039-3.015C35.934,15.291,29.646,10.461,29.646,10.461z M4.37,27.114
|
||||
c-0.015-0.164,0.006-2.549-0.005-2.713H8.05v-1.19H4.624c0-0.014-0.259,0.002-0.259,0.002c0.145-3.085,1.32-6.163,3.539-8.59
|
||||
l0.093-0.1l0.166,0.144l2.452,2.454l0.77-0.772L8.78,13.746c2.358-2.156,5.35-3.393,8.542-3.535l0.185-0.001
|
||||
c0,0,0.077-0.003,0.072,0.046v3.634h0.981v-3.679c0.484,0.02,0.968,0.077,1.445,0.152c2.741,0.362,5.289,1.545,7.352,3.43
|
||||
l-2.6,2.602l0.723,0.726l2.497-2.498l0.138-0.111l0.118,0.156c2.159,2.36,3.394,5.35,3.539,8.543h-3.681v1.19l3.698-0.005
|
||||
c0,0,0.003,2.561-0.01,2.709L4.37,27.114z M22.8,18.528c0,0-5.844,1.792-6.963,2.909c-1.121,1.122-1.121,2.935,0.002,4.057
|
||||
c1.117,1.121,2.932,1.121,4.054,0C21.011,24.372,22.8,18.528,22.8,18.528z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,7 +0,0 @@
|
|||
/*
|
||||
* Public API Surface of speedtest
|
||||
*/
|
||||
|
||||
export * from './lib/services/speedtest.service';
|
||||
export * from './lib/components/speedtest.component';
|
||||
export * from './lib/speedtest.module';
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"paths": {
|
||||
"speedtest": [
|
||||
"dist/speedtest"
|
||||
],
|
||||
"speedtest/*": [
|
||||
"dist/speedtest/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rulesDirectory": [
|
||||
"codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"array-type": false,
|
||||
"arrow-parens": false,
|
||||
"deprecation": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"interface-name": false,
|
||||
"max-classes-per-file": false,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-consecutive-blank-lines": false,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-empty": false,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-non-null-assertion": true,
|
||||
"no-redundant-jsdoc": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-var-requires": false,
|
||||
"object-literal-key-quotes": [
|
||||
true,
|
||||
"as-needed"
|
||||
],
|
||||
"object-literal-sort-keys": false,
|
||||
"ordered-imports": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"trailing-comma": false,
|
||||
"component-class-suffix": true,
|
||||
"contextual-lifecycle": true,
|
||||
"directive-class-suffix": true,
|
||||
"no-conflicting-lifecycle": true,
|
||||
"no-host-metadata-property": true,
|
||||
"no-input-rename": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-output-native": true,
|
||||
"no-output-on-prefix": true,
|
||||
"no-output-rename": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
"template-banana-in-box": true,
|
||||
"template-no-negated-async": true,
|
||||
"use-lifecycle-interface": true,
|
||||
"use-pipe-transform-interface": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue