added current tasks view
This commit is contained in:
parent
f22eb5d8bd
commit
c3d1f9e9b0
@ -3,3 +3,4 @@ from .player import blueprint as player_blueprint
|
||||
from .fm import blueprint as fm_blueprint
|
||||
from .spotfm import blueprint as spotfm_blueprint
|
||||
from .spotify import blueprint as spotify_blueprint
|
||||
from .admin import blueprint as admin_blueprint
|
||||
|
43
music/api/admin.py
Normal file
43
music/api/admin.py
Normal file
@ -0,0 +1,43 @@
|
||||
from flask import Blueprint, jsonify
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from google.cloud import firestore
|
||||
from google.cloud import tasks_v2
|
||||
|
||||
from music.api.decorators import login_or_basic_auth, admin_required
|
||||
|
||||
blueprint = Blueprint('admin-api', __name__)
|
||||
db = firestore.Client()
|
||||
|
||||
tasker = tasks_v2.CloudTasksClient()
|
||||
task_path = tasker.queue_path('sarsooxyz', 'europe-west2', 'spotify-executions')
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@blueprint.route('/tasks', methods=['GET'])
|
||||
@login_or_basic_auth
|
||||
@admin_required
|
||||
def get_tasks(username=None):
|
||||
|
||||
tasks = [i for i in tasker.list_tasks(task_path)]
|
||||
|
||||
urls = {}
|
||||
for task in tasks:
|
||||
if urls.get(task.app_engine_http_request.relative_uri):
|
||||
urls[task.app_engine_http_request.relative_uri] += 1
|
||||
else:
|
||||
urls[task.app_engine_http_request.relative_uri] = 1
|
||||
|
||||
response = {
|
||||
'tasks': [{
|
||||
'url': i,
|
||||
'count': j,
|
||||
'scheduled_times': [datetime.fromtimestamp(k.schedule_time.seconds) for k in tasks
|
||||
if k.app_engine_http_request.relative_uri == i]
|
||||
} for i, j in urls.items()],
|
||||
'total_tasks': len(tasks),
|
||||
}
|
||||
return jsonify(response), 200
|
@ -4,7 +4,8 @@ from google.cloud import firestore
|
||||
import os
|
||||
|
||||
from music.auth import auth_blueprint
|
||||
from music.api import api_blueprint, player_blueprint, fm_blueprint, spotfm_blueprint, spotify_blueprint
|
||||
from music.api import api_blueprint, player_blueprint, fm_blueprint, \
|
||||
spotfm_blueprint, spotify_blueprint, admin_blueprint
|
||||
|
||||
db = firestore.Client()
|
||||
|
||||
@ -16,6 +17,7 @@ app.register_blueprint(player_blueprint, url_prefix='/api/player')
|
||||
app.register_blueprint(fm_blueprint, url_prefix='/api/fm')
|
||||
app.register_blueprint(spotfm_blueprint, url_prefix='/api/spotfm')
|
||||
app.register_blueprint(spotify_blueprint, url_prefix='/api/spotify')
|
||||
app.register_blueprint(admin_blueprint, url_prefix='/api/admin')
|
||||
|
||||
|
||||
@app.route('/')
|
||||
|
@ -4,6 +4,7 @@ const axios = require('axios');
|
||||
|
||||
import Lock from "./Lock.js";
|
||||
import Functions from "./Functions.js";
|
||||
import Tasks from "./Tasks.js";
|
||||
|
||||
class Admin extends Component {
|
||||
render(){
|
||||
@ -12,10 +13,12 @@ class Admin extends Component {
|
||||
<ul className="navbar" style={{width: "100%"}}>
|
||||
<li><Link to={`${this.props.match.url}/lock`}>lock accounts</Link></li>
|
||||
<li><Link to={`${this.props.match.url}/functions`}>functions</Link></li>
|
||||
<li><Link to={`${this.props.match.url}/tasks`}>tasks</Link></li>
|
||||
</ul>
|
||||
|
||||
<Route path={`${this.props.match.url}/lock`} component={Lock} />
|
||||
<Route path={`${this.props.match.url}/functions`} component={Functions} />
|
||||
<Route path={`${this.props.match.url}/tasks`} component={Tasks} />
|
||||
|
||||
</div>
|
||||
);
|
||||
|
@ -9,10 +9,24 @@ class Functions extends Component {
|
||||
super(props);
|
||||
|
||||
this.runAllUsers = this.runAllUsers.bind(this);
|
||||
this.runStats = this.runStats.bind(this);
|
||||
}
|
||||
|
||||
runAllUsers(event){
|
||||
axios.get('/api/playlist/run/users')
|
||||
.then((response) => {
|
||||
showMessage('users run');
|
||||
})
|
||||
.catch((error) => {
|
||||
showMessage(`error running all users (${error.response.status})`);
|
||||
});
|
||||
}
|
||||
|
||||
runStats(event){
|
||||
axios.get('/api/spotfm/playlist/refresh/users')
|
||||
.then((response) => {
|
||||
showMessage('stats run');
|
||||
})
|
||||
.catch((error) => {
|
||||
showMessage(`error running all users (${error.response.status})`);
|
||||
});
|
||||
@ -34,6 +48,11 @@ class Functions extends Component {
|
||||
<button className="full-width button" onClick={this.runAllUsers}>run all users</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button className="full-width button" onClick={this.runStats}>run stats</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>);
|
||||
}
|
||||
|
71
src/js/Admin/Tasks.js
Normal file
71
src/js/Admin/Tasks.js
Normal file
@ -0,0 +1,71 @@
|
||||
import React, { Component } from "react";
|
||||
const axios = require('axios');
|
||||
|
||||
import showMessage from "../Toast.js"
|
||||
|
||||
class Tasks extends Component {
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
total_tasks: 0,
|
||||
tasks: [],
|
||||
schedule_times: []
|
||||
}
|
||||
this.getTasks();
|
||||
}
|
||||
|
||||
getTasks(){
|
||||
var self = this;
|
||||
axios.get('/api/admin/tasks')
|
||||
.then((response) => {
|
||||
self.setState({
|
||||
total_tasks: response.data.total_tasks,
|
||||
tasks: response.data.tasks
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
showMessage(`error getting tasks (${error.response.status})`);
|
||||
});
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<table className="app-table max-width">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<h1 className="text-no-select full-width center-text ui-text">running tasks</h1>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{ this.state.tasks.map((entry) => <TaskType url={entry.url} count={entry.count} times={entry.scheduled_times} key={entry.url}/>)}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="text-no-select full-width center-text ui-text" colSpan='2'>
|
||||
<b>{this.state.total_tasks}</b> running tasks
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>);
|
||||
}
|
||||
}
|
||||
|
||||
function TaskType(props) {
|
||||
return (
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="text-no-select full-width center-text ui-text" colSpan='2'>
|
||||
{props.url}: {props.count}
|
||||
</td>
|
||||
</tr>
|
||||
{props.times.map((entry) => <tr key={entry}>
|
||||
<td colSpan='2' className="text-no-select full-width center-text ui-text">
|
||||
{entry}
|
||||
</td>
|
||||
</tr>)}
|
||||
</tbody>
|
||||
);
|
||||
}
|
||||
|
||||
export default Tasks;
|
Loading…
Reference in New Issue
Block a user