Bulk User management
This commit is contained in:
		
							parent
							
								
									c810c5275a
								
							
						
					
					
						commit
						0992bafe30
					
				
							
								
								
									
										39
									
								
								cps/admin.py
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								cps/admin.py
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -35,6 +35,7 @@ from flask import Blueprint, flash, redirect, url_for, abort, request, make_resp
 | 
			
		|||
from flask_login import login_required, current_user, logout_user, confirm_login
 | 
			
		||||
from flask_babel import gettext as _
 | 
			
		||||
from sqlalchemy import and_
 | 
			
		||||
from sqlalchemy.orm.attributes import flag_modified
 | 
			
		||||
from sqlalchemy.exc import IntegrityError, OperationalError, InvalidRequestError
 | 
			
		||||
from sqlalchemy.sql.expression import func, or_
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -225,11 +226,12 @@ def edit_user_table():
 | 
			
		|||
    return render_title_template("user_table.html",
 | 
			
		||||
                                 users=allUser.all(),
 | 
			
		||||
                                 visiblility=visibility,
 | 
			
		||||
                                 all_roles = constants.ALL_ROLES,
 | 
			
		||||
                                 all_roles=constants.ALL_ROLES,
 | 
			
		||||
                                 sidebar_settings=constants.sidebar_settings,
 | 
			
		||||
                                 title=_(u"Edit Users"),
 | 
			
		||||
                                 page="usertable")
 | 
			
		||||
 | 
			
		||||
@admi.route("/axjax/listusers")
 | 
			
		||||
@admi.route("/ajax/listusers")
 | 
			
		||||
@login_required
 | 
			
		||||
@admin_required
 | 
			
		||||
def list_users():
 | 
			
		||||
| 
						 | 
				
			
			@ -242,8 +244,11 @@ def list_users():
 | 
			
		|||
        all_user = all_user.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS)
 | 
			
		||||
    total_count = all_user.count()
 | 
			
		||||
    if search:
 | 
			
		||||
        users = all_user.filter().offset(off).limit(limit).all()
 | 
			
		||||
        filtered_count = users.length()
 | 
			
		||||
        users = all_user.filter(or_(func.lower(ub.User.nickname).ilike("%" + search + "%"),
 | 
			
		||||
                                    func.lower(ub.User.kindle_mail).ilike("%" + search + "%"),
 | 
			
		||||
                                    func.lower(ub.User.email).ilike("%" + search + "%")))\
 | 
			
		||||
            .offset(off).limit(limit).all()
 | 
			
		||||
        filtered_count = len(users)
 | 
			
		||||
    else:
 | 
			
		||||
        users = all_user.offset(off).limit(limit).all()
 | 
			
		||||
        filtered_count = total_count
 | 
			
		||||
| 
						 | 
				
			
			@ -255,6 +260,14 @@ def list_users():
 | 
			
		|||
    response.headers["Content-Type"] = "application/json; charset=utf-8"
 | 
			
		||||
    return response
 | 
			
		||||
 | 
			
		||||
@admi.route("/ajax/deleteuser")
 | 
			
		||||
@login_required
 | 
			
		||||
@admin_required
 | 
			
		||||
def delete_user():
 | 
			
		||||
    # ToDo User delete check also not last one
 | 
			
		||||
    pass
 | 
			
		||||
    return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@admi.route("/axjax/editlistusers/<param>", methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +298,24 @@ def edit_list_user(param):
 | 
			
		|||
    return ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@admi.route("/ajax/user_table_settings", methods=['POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
@admin_required
 | 
			
		||||
def update_table_settings():
 | 
			
		||||
    # ToDo: Save table settings
 | 
			
		||||
    current_user.view_settings['useredit'] = json.loads(request.data)
 | 
			
		||||
    try:
 | 
			
		||||
        try:
 | 
			
		||||
            flag_modified(current_user, "view_settings")
 | 
			
		||||
        except AttributeError:
 | 
			
		||||
            pass
 | 
			
		||||
        ub.session.commit()
 | 
			
		||||
    except (InvalidRequestError, OperationalError):
 | 
			
		||||
        log.error("Invalid request received: %r ", request, )
 | 
			
		||||
        return "Invalid request", 400
 | 
			
		||||
    return ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@admi.route("/admin/viewconfig", methods=["POST"])
 | 
			
		||||
@login_required
 | 
			
		||||
@admin_required
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,6 +88,26 @@ SIDEBAR_ARCHIVED        = 1 << 15
 | 
			
		|||
SIDEBAR_DOWNLOAD        = 1 << 16
 | 
			
		||||
SIDEBAR_LIST            = 1 << 17
 | 
			
		||||
 | 
			
		||||
sidebar_settings = {
 | 
			
		||||
                "detail_random": DETAIL_RANDOM,
 | 
			
		||||
                "sidebar_language": SIDEBAR_LANGUAGE,
 | 
			
		||||
                "sidebar_series": SIDEBAR_SERIES,
 | 
			
		||||
                "sidebar_category": SIDEBAR_CATEGORY,
 | 
			
		||||
                "sidebar_random": SIDEBAR_RANDOM,
 | 
			
		||||
                "sidebar_author": SIDEBAR_AUTHOR,
 | 
			
		||||
                "sidebar_best_rated": SIDEBAR_BEST_RATED,
 | 
			
		||||
                "sidebar_read_and_unread": SIDEBAR_READ_AND_UNREAD,
 | 
			
		||||
                "sidebar_recent": SIDEBAR_RECENT,
 | 
			
		||||
                "sidebar_sorted": SIDEBAR_SORTED,
 | 
			
		||||
                "sidebar_publisher": SIDEBAR_PUBLISHER,
 | 
			
		||||
                "sidebar_rating": SIDEBAR_RATING,
 | 
			
		||||
                "sidebar_format": SIDEBAR_FORMAT,
 | 
			
		||||
                "sidebar_archived": SIDEBAR_ARCHIVED,
 | 
			
		||||
                "sidebar_download": SIDEBAR_DOWNLOAD,
 | 
			
		||||
                "sidebar_list": SIDEBAR_LIST,
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ADMIN_USER_ROLES        = sum(r for r in ALL_ROLES.values()) & ~ROLE_ANONYMOUS
 | 
			
		||||
ADMIN_USER_SIDEBAR      = (SIDEBAR_LIST << 1) - 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,7 +116,7 @@ $(function() {
 | 
			
		|||
        search: true,
 | 
			
		||||
        showColumns: true,
 | 
			
		||||
        searchAlign: "left",
 | 
			
		||||
        showSearchButton : false,
 | 
			
		||||
        showSearchButton : true,
 | 
			
		||||
        searchOnEnterKey: true,
 | 
			
		||||
        checkboxHeader: false,
 | 
			
		||||
        maintainMetaData: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -377,15 +377,24 @@ $(function() {
 | 
			
		|||
        search: true,
 | 
			
		||||
        showColumns: true,
 | 
			
		||||
        searchAlign: "left",
 | 
			
		||||
        showSearchButton : false,
 | 
			
		||||
        showSearchButton : true,
 | 
			
		||||
        searchOnEnterKey: true,
 | 
			
		||||
        checkboxHeader: false,
 | 
			
		||||
        checkboxHeader: true,
 | 
			
		||||
        maintainMetaData: true,
 | 
			
		||||
        responseHandler: responseHandler,
 | 
			
		||||
        columns: user_column,
 | 
			
		||||
        formatNoMatches: function () {
 | 
			
		||||
            return "";
 | 
			
		||||
        },
 | 
			
		||||
        onPostBody () {
 | 
			
		||||
            // var elements = ;
 | 
			
		||||
            // Remove all checkboxes from Headers for showing the texts in the column selector
 | 
			
		||||
            $('.columns [data-field]').each(function(){
 | 
			
		||||
                var elText = $(this).next().text();
 | 
			
		||||
                $(this).next().empty();
 | 
			
		||||
                $(this).next().text(elText);
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        // eslint-disable-next-line no-unused-vars
 | 
			
		||||
        /*onEditableSave: function (field, row, oldvalue, $el) {
 | 
			
		||||
            if (field === "title" || field === "authors") {
 | 
			
		||||
| 
						 | 
				
			
			@ -411,22 +420,47 @@ $(function() {
 | 
			
		|||
            var hidden  = $("#user-table").bootstrapTable("getHiddenColumns");
 | 
			
		||||
            var st = "";
 | 
			
		||||
            visible.forEach(function(item) {
 | 
			
		||||
                st += "\"" + item.field + "\":\"" + "true" + "\",";
 | 
			
		||||
                st += "\"" + item.name + "\":\"" + "true" + "\",";
 | 
			
		||||
            });
 | 
			
		||||
            hidden.forEach(function(item) {
 | 
			
		||||
                st += "\"" + item.field + "\":\"" + "false" + "\",";
 | 
			
		||||
                st += "\"" + item.name + "\":\"" + "false" + "\",";
 | 
			
		||||
            });
 | 
			
		||||
            st = st.slice(0, -1);
 | 
			
		||||
            /*$.ajax({
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                method:"post",
 | 
			
		||||
                contentType: "application/json; charset=utf-8",
 | 
			
		||||
                dataType: "json",
 | 
			
		||||
                url: window.location.pathname + "/../../ajax/table_settings",
 | 
			
		||||
                url: window.location.pathname + "/../../ajax/user_table_settings",
 | 
			
		||||
                data: "{" + st + "}",
 | 
			
		||||
            });*/
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function user_handle (userId) {
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            method:"post",
 | 
			
		||||
            url: window.location.pathname + "/../../ajax/deleteuser",
 | 
			
		||||
            data: {"userid":userId}
 | 
			
		||||
        });
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            method:"get",
 | 
			
		||||
            url: window.location.pathname + "/../../ajax/listusers",
 | 
			
		||||
            async: true,
 | 
			
		||||
            timeout: 900,
 | 
			
		||||
            success:function(data) {
 | 
			
		||||
                $("#user-table").bootstrapTable("load", data);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $("#user-table").on("click-cell.bs.table", function (field, value, row, $element) {
 | 
			
		||||
        if (value === "denied_column_value") {
 | 
			
		||||
            ConfirmDialog("btndeluser", $element.id, user_handle);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /*$("#user-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table",
 | 
			
		||||
    function (e, rowsAfter, rowsBefore) {
 | 
			
		||||
| 
						 | 
				
			
			@ -474,7 +508,7 @@ function EbookActions (value, row) {
 | 
			
		|||
/* Function for deleting books */
 | 
			
		||||
function UserActions (value, row) {
 | 
			
		||||
    return [
 | 
			
		||||
        "<div class=\"user-remove\" data-toggle=\"modal\" data-target=\"#GeneralDeleteModal\" data-ajax=\"1\" data-delete-id=\"" + row.id + "\" title=\"Remove\">",
 | 
			
		||||
        "<div class=\"user-remove\" data-target=\"#GeneralDeleteModal\" title=\"Remove\">",
 | 
			
		||||
        "<i class=\"glyphicon glyphicon-trash\"></i>",
 | 
			
		||||
        "</div>"
 | 
			
		||||
    ].join("");
 | 
			
		||||
| 
						 | 
				
			
			@ -507,3 +541,8 @@ function checkboxChange(checkbox, index){
 | 
			
		|||
        reinit: false
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function checkboxHeader(element) {
 | 
			
		||||
    console.log("hallo");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,8 @@
 | 
			
		|||
{% extends "layout.html" %}
 | 
			
		||||
{% macro user_table_row(parameter, edit_text, show_text, validate) -%}
 | 
			
		||||
<th data-field="{{ parameter }}" id="{{ parameter }}" data-sortable="true"
 | 
			
		||||
    data-visible = "{{visiblility.get(parameter)}}"
 | 
			
		||||
    data-name="{{ parameter }}"
 | 
			
		||||
    data-visible="{{visiblility.get(parameter)}}"
 | 
			
		||||
    data-editable-type="text"
 | 
			
		||||
    data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}"
 | 
			
		||||
    data-editable-title="{{ edit_text }}"
 | 
			
		||||
| 
						 | 
				
			
			@ -16,28 +17,44 @@
 | 
			
		|||
{% endblock %}
 | 
			
		||||
{% block body %}
 | 
			
		||||
<h2 class="{{page}}">{{_(title)}}</h2>
 | 
			
		||||
    <table>
 | 
			
		||||
    </table>
 | 
			
		||||
    <table id="user-table" class="table table-no-bordered table-striped"
 | 
			
		||||
           data-url="{{url_for('admin.list_users')}}">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th data-buttontext="{{_('Edit User')}}" data-formatter="singleUserFormatter"></th>
 | 
			
		||||
            <th data-field="state" data-checkbox="true" data-sortable="true"></th>
 | 
			
		||||
            <th data-field="id" id="id" data-visible="false" data-switchable="false"></th>
 | 
			
		||||
            <th data-name="edit" data-buttontext="{{_('Edit User')}}" data-visible="{{visiblility.get('edit')}}" data-formatter="singleUserFormatter">{{_('Edit')}}</th>
 | 
			
		||||
            <th data-name="state" data-field="state" data-checkbox="true" data-visible="{{visiblility.get('state')}}" data-sortable="true"></th>
 | 
			
		||||
            <th data-name="id" data-field="id" id="id" data-visible="false" data-switchable="false"></th>
 | 
			
		||||
            {{ user_table_row('nickname', _('Enter Username'), _('Username'), true) }}
 | 
			
		||||
            {{ user_table_row('email', _('Enter E-mail Address'), _('E-mail Address'), true) }}
 | 
			
		||||
            {{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), true) }}
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.admin_role}}" data-formatter="checkboxFormatter">{{_('Admin')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.download_role}}" data-formatter="checkboxFormatter">{{_('Upload')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.upload_role}}" data-formatter="checkboxFormatter">{{_('Download')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.edit_role}}" data-formatter="checkboxFormatter">{{_('Edit')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.passwd_role}}" data-formatter="checkboxFormatter">{{_('Change Password')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.edit_shelf_role}}" data-formatter="checkboxFormatter">{{_('Edit Public Shelfs')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.delete_role}}" data-formatter="checkboxFormatter">{{_('Delete')}}</th>
 | 
			
		||||
            <th data-field="role" data-column="{{all_roles.viewer_role}}" data-formatter="checkboxFormatter">{{_('View')}}</th>
 | 
			
		||||
            <th data-name="admin_role" data-field="role" data-visible="{{visiblility.get('admin_role')}}" data-column="{{all_roles.admin_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Admin')}}</th>
 | 
			
		||||
            <th data-name="download_role" data-field="role" data-visible="{{visiblility.get('download_role')}}" data-column="{{all_roles.download_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Upload')}}</th>
 | 
			
		||||
            <th data-name="upload_role" data-field="role" data-visible="{{visiblility.get('upload_role')}}" data-column="{{all_roles.upload_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Download')}}</th>
 | 
			
		||||
            <th data-name="edit_role" data-field="role" data-visible="{{visiblility.get('edit_role')}}" data-column="{{all_roles.edit_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Edit')}}</th>
 | 
			
		||||
            <th data-name="passwd_role" data-field="role" data-visible="{{visiblility.get('passwd_role')}}" data-column="{{all_roles.passwd_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Change Password')}}</th>
 | 
			
		||||
            <th data-name="edit_shelf_role" data-field="role" data-visible="{{visiblility.get('edit_shelf_role')}}" data-column="{{all_roles.edit_shelf_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Edit Public Shelfs')}}</th>
 | 
			
		||||
            <th data-name="delete_role" data-field="role" data-visible="{{visiblility.get('delete_role')}}" data-column="{{all_roles.delete_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('Delete')}}</th>
 | 
			
		||||
            <th data-name="viewer_role" data-field="role" data-visible="{{visiblility.get('viewer_role')}}" data-column="{{all_roles.viewer_role}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chkhead" onchange="checkboxHeader(this)"><br>{{_('View')}}</th>
 | 
			
		||||
            {{ user_table_row('denied_tags', _("Enter Users's Locale"), _("Users's Locale"), true) }}
 | 
			
		||||
            {{ user_table_row('allowed_tags', _("Enter Users's Locale"), _("Users's Locale"), true) }}
 | 
			
		||||
            {{ user_table_row('allowed_column_value', _("Enter Users's Locale"), _("Users's Locale"), true) }}
 | 
			
		||||
            {{ user_table_row('denied_column_value', _("Enter Users's Locale"), _("Users's Locale"), true) }}
 | 
			
		||||
            <th data-name="detail_random" data-field="sidebar_view" data-visible="{{visiblility.get('detail_random')}}" data-column="{{sidebar_settings.detail_random}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show Random Books in Detail View')}}</th>
 | 
			
		||||
            <th data-name="sidebar_language" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_language')}}" data-column="{{sidebar_settings.sidebar_language}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show language selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_series" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_series')}}" data-column="{{sidebar_settings.sidebar_series}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show series selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_category" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_category')}}" data-column="{{sidebar_settings.sidebar_category}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{ _('Show category selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_random" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_random')}}" data-column="{{sidebar_settings.sidebar_random}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{ _('Show random books')}}</th>
 | 
			
		||||
            <th data-name="sidebar_author" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_author')}}" data-column="{{sidebar_settings.sidebar_author}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show author selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_best_rated" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_best_rated')}}" data-column="{{sidebar_settings.sidebar_best_rated}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show Top Rated Books')}}</th>
 | 
			
		||||
            <th data-name="sidebar_read_and_unread" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_read_and_unread')}}" data-column="{{sidebar_settings.sidebar_read_and_unread}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show random books')}}</th>
 | 
			
		||||
            <th data-name="sidebar_publisher" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_publisher')}}" data-column="{{sidebar_settings.sidebar_publisher}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show publisher selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_rating" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_rating')}}" data-column="{{sidebar_settings.sidebar_rating}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show ratings selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_format" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_format')}}" data-column="{{sidebar_settings.sidebar_format}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show file formats selection')}}</th>
 | 
			
		||||
            <th data-name="sidebar_archived" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_archived')}}" data-column="{{sidebar_settings.sidebar_archived}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show archived books')}}</th>
 | 
			
		||||
            <th data-name="sidebar_download" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_download')}}" data-column="{{sidebar_settings.sidebar_download}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show Downloaded Books')}}</th>
 | 
			
		||||
            <th data-name="sidebar_list" data-field="sidebar_view" data-visible="{{visiblility.get('sidebar_list')}}" data-column="{{sidebar_settings.sidebar_list}}" data-formatter="checkboxFormatter"><input type="checkbox" class="chk" ><br>{{_('Show Books List')}}</th>
 | 
			
		||||
            <th data-align="right" data-formatter="UserActions" data-switchable="false">{{_('Delete User')}}</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,14 +37,14 @@
 | 
			
		|||
      <div class="row">
 | 
			
		||||
        <div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
 | 
			
		||||
            
 | 
			
		||||
            <p class='text-justify attribute'><strong>Start Time: </strong>2021-02-08 20:40:55</p>
 | 
			
		||||
            <p class='text-justify attribute'><strong>Start Time: </strong>2021-02-09 20:40:28</p>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col-xs-6 col-md-6 col-sm-offset-3">
 | 
			
		||||
            
 | 
			
		||||
            <p class='text-justify attribute'><strong>Stop Time: </strong>2021-02-08 23:09:33</p>
 | 
			
		||||
            <p class='text-justify attribute'><strong>Stop Time: </strong>2021-02-09 23:08:52</p>
 | 
			
		||||
            
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -1595,12 +1595,12 @@
 | 
			
		|||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <tr id="su" class="errorClass">
 | 
			
		||||
    <tr id="su" class="passClass">
 | 
			
		||||
        <td>TestKoboSync</td>
 | 
			
		||||
        <td class="text-center">9</td>
 | 
			
		||||
        <td class="text-center">8</td>
 | 
			
		||||
        <td class="text-center">9</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">1</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">
 | 
			
		||||
            <a onclick="showClassDetail('c18', 9)">Detail</a>
 | 
			
		||||
| 
						 | 
				
			
			@ -1609,31 +1609,11 @@
 | 
			
		|||
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
        <tr id="et18.1" class="none bg-info">
 | 
			
		||||
        <tr id='pt18.1' class='hiddenRow bg-success'>
 | 
			
		||||
            <td>
 | 
			
		||||
                <div class='testcase'>TestKoboSync - test_book_download</div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td colspan='6'>
 | 
			
		||||
                <div class="text-center">
 | 
			
		||||
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et18.1')">ERROR</a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup start-->
 | 
			
		||||
                <div id="div_et18.1" class="popup_window test_output" style="display:none;">
 | 
			
		||||
                    <div class='close_button pull-right'>
 | 
			
		||||
                        <button type="button" class="close" aria-label="Close" onfocus='this.blur();'
 | 
			
		||||
                                onclick='document.getElementById('div_et18.1').style.display='none'"><span
 | 
			
		||||
                                aria-hidden="true">×</span></button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="text-left pull-left">
 | 
			
		||||
                        <pre class="text-left">Traceback (most recent call last):
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 593, in test_book_download
 | 
			
		||||
    print(data[0]['NewEntitlement']['BookMetadata']['DownloadUrls'][1]['Url'])
 | 
			
		||||
IndexError: list index out of range</pre>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="clearfix"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup end-->
 | 
			
		||||
            </td>
 | 
			
		||||
            <td colspan='6' align='center'>PASS</td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -2376,11 +2356,11 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <tr id="su" class="passClass">
 | 
			
		||||
    <tr id="su" class="failClass">
 | 
			
		||||
        <td>TestRegister</td>
 | 
			
		||||
        <td class="text-center">8</td>
 | 
			
		||||
        <td class="text-center">8</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">7</td>
 | 
			
		||||
        <td class="text-center">1</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">
 | 
			
		||||
| 
						 | 
				
			
			@ -2453,11 +2433,31 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
        <tr id='pt25.8' class='hiddenRow bg-success'>
 | 
			
		||||
        <tr id="ft25.8" class="none bg-danger">
 | 
			
		||||
            <td>
 | 
			
		||||
                <div class='testcase'>TestRegister - test_user_change_password</div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td colspan='6' align='center'>PASS</td>
 | 
			
		||||
            <td colspan='6'>
 | 
			
		||||
                <div class="text-center">
 | 
			
		||||
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft25.8')">FAIL</a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup start-->
 | 
			
		||||
                <div id="div_ft25.8" class="popup_window test_output" style="display:none;">
 | 
			
		||||
                    <div class='close_button pull-right'>
 | 
			
		||||
                        <button type="button" class="close" aria-label="Close" onfocus='this.blur();'
 | 
			
		||||
                                onclick='document.getElementById('div_ft25.8').style.display='none'"><span
 | 
			
		||||
                                aria-hidden="true">×</span></button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="text-left pull-left">
 | 
			
		||||
                        <pre class="text-left">Traceback (most recent call last):
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/test/test_register.py", line 185, in test_user_change_password
 | 
			
		||||
    self.assertTrue(self.edit_user(u'upasswd', { 'resend_password':1}))
 | 
			
		||||
AssertionError: False is not true</pre>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="clearfix"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup end-->
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -2594,12 +2594,12 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <tr id="su" class="skipClass">
 | 
			
		||||
    <tr id="su" class="errorClass">
 | 
			
		||||
        <td>TestUpdater</td>
 | 
			
		||||
        <td class="text-center">8</td>
 | 
			
		||||
        <td class="text-center">7</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">0</td>
 | 
			
		||||
        <td class="text-center">5</td>
 | 
			
		||||
        <td class="text-center">1</td>
 | 
			
		||||
        <td class="text-center">1</td>
 | 
			
		||||
        <td class="text-center">1</td>
 | 
			
		||||
        <td class="text-center">
 | 
			
		||||
            <a onclick="showClassDetail('c27', 8)">Detail</a>
 | 
			
		||||
| 
						 | 
				
			
			@ -2653,11 +2653,31 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
        <tr id='pt27.6' class='hiddenRow bg-success'>
 | 
			
		||||
        <tr id="ft27.6" class="none bg-danger">
 | 
			
		||||
            <td>
 | 
			
		||||
                <div class='testcase'>TestUpdater - test_perform_update_stable_errors</div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td colspan='6' align='center'>PASS</td>
 | 
			
		||||
            <td colspan='6'>
 | 
			
		||||
                <div class="text-center">
 | 
			
		||||
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft27.6')">FAIL</a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup start-->
 | 
			
		||||
                <div id="div_ft27.6" class="popup_window test_output" style="display:none;">
 | 
			
		||||
                    <div class='close_button pull-right'>
 | 
			
		||||
                        <button type="button" class="close" aria-label="Close" onfocus='this.blur();'
 | 
			
		||||
                                onclick='document.getElementById('div_ft27.6').style.display='none'"><span
 | 
			
		||||
                                aria-hidden="true">×</span></button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="text-left pull-left">
 | 
			
		||||
                        <pre class="text-left">Traceback (most recent call last):
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 312, in test_perform_update_stable_errors
 | 
			
		||||
    self.assertTrue('HTTP Error' in self.check_element_on_page((By.ID, "DialogContent")).text)
 | 
			
		||||
AssertionError: False is not true</pre>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="clearfix"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup end-->
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -2688,11 +2708,41 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
        <tr id='pt27.8' class='hiddenRow bg-success'>
 | 
			
		||||
        <tr id="et27.8" class="none bg-info">
 | 
			
		||||
            <td>
 | 
			
		||||
                <div class='testcase'>TestUpdater - test_reconnect_database</div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td colspan='6' align='center'>PASS</td>
 | 
			
		||||
            <td colspan='6'>
 | 
			
		||||
                <div class="text-center">
 | 
			
		||||
                    <a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et27.8')">ERROR</a>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup start-->
 | 
			
		||||
                <div id="div_et27.8" class="popup_window test_output" style="display:none;">
 | 
			
		||||
                    <div class='close_button pull-right'>
 | 
			
		||||
                        <button type="button" class="close" aria-label="Close" onfocus='this.blur();'
 | 
			
		||||
                                onclick='document.getElementById('div_et27.8').style.display='none'"><span
 | 
			
		||||
                                aria-hidden="true">×</span></button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="text-left pull-left">
 | 
			
		||||
                        <pre class="text-left">Traceback (most recent call last):
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 371, in test_reconnect_database
 | 
			
		||||
    self.reconnect_database()
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 359, in reconnect_database
 | 
			
		||||
    self.driver.find_element_by_id('restart_database').click()
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 80, in click
 | 
			
		||||
    self._execute(Command.CLICK_ELEMENT)
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
 | 
			
		||||
    return self._parent.execute(command, params)
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
 | 
			
		||||
    self.error_handler.check_response(response)
 | 
			
		||||
  File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
 | 
			
		||||
    raise exception_class(message, screen, stacktrace)
 | 
			
		||||
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <div id="restart_database" class="btn btn-default"> is not clickable at point (553,718) because another element <div id="StatusDialog" class="modal fade in"> obscures it</pre>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="clearfix"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!--css div popup end-->
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -3399,8 +3449,8 @@ IndexError: list index out of range</pre>
 | 
			
		|||
    <tr id='total_row' class="text-center bg-grey">
 | 
			
		||||
        <td>Total</td>
 | 
			
		||||
        <td>299</td>
 | 
			
		||||
        <td>291</td>
 | 
			
		||||
        <td>0</td>
 | 
			
		||||
        <td>289</td>
 | 
			
		||||
        <td>2</td>
 | 
			
		||||
        <td>1</td>
 | 
			
		||||
        <td>7</td>
 | 
			
		||||
        <td> </td>
 | 
			
		||||
| 
						 | 
				
			
			@ -3430,7 +3480,7 @@ IndexError: list index out of range</pre>
 | 
			
		|||
          
 | 
			
		||||
            <tr>
 | 
			
		||||
              <th>Platform</th>
 | 
			
		||||
              <td>Linux 5.8.0-41-generic #46~20.04.1-Ubuntu SMP Mon Jan 18 17:52:23 UTC 2021 x86_64 x86_64</td>
 | 
			
		||||
              <td>Linux 5.8.0-43-generic #49~20.04.1-Ubuntu SMP Fri Feb 5 09:57:56 UTC 2021 x86_64 x86_64</td>
 | 
			
		||||
              <td>Basic</td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          
 | 
			
		||||
| 
						 | 
				
			
			@ -3766,7 +3816,7 @@ IndexError: list index out of range</pre>
 | 
			
		|||
</div>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
    drawCircle(291, 0, 1, 7);
 | 
			
		||||
    drawCircle(289, 2, 1, 7);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user