Import Upstream version 3.0.2.0kylin6k70.30update1
|
@ -0,0 +1,25 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
include($$PWD/../commonfunc/commonfunc.pri)
|
||||
HEADERS += \
|
||||
$$PWD/kabuttonproxystyle.h \
|
||||
$$PWD/kagroupbutton.h \
|
||||
$$PWD/kainfotitle.h \
|
||||
$$PWD/kalabel.h \
|
||||
$$PWD/kaslider.h \
|
||||
$$PWD/katabbar.h \
|
||||
$$PWD/katabbutton.h \
|
||||
$$PWD/kdriveinfoitem.h \
|
||||
$$PWD/kinfolistitem.h \
|
||||
$$PWD/loadingwidget.h
|
||||
SOURCES += \
|
||||
$$PWD/kabuttonproxystyle.cpp \
|
||||
$$PWD/kagroupbutton.cpp \
|
||||
$$PWD/kainfotitle.cpp \
|
||||
$$PWD/kalabel.cpp \
|
||||
$$PWD/kaslider.cpp \
|
||||
$$PWD/katabbar.cpp \
|
||||
$$PWD/katabbutton.cpp \
|
||||
$$PWD/kdriveinfoitem.cpp \
|
||||
$$PWD/kinfolistitem.cpp \
|
||||
$$PWD/loadingwidget.cpp
|
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kabuttonproxystyle.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStyleOption>
|
||||
#include <QStyle>
|
||||
#include <QDebug>
|
||||
|
||||
KAButtonProxyStyle::KAButtonProxyStyle(QStyle *style)
|
||||
: QProxyStyle(style)
|
||||
{
|
||||
}
|
||||
|
||||
KAButtonProxyStyle::KAButtonProxyStyle(const QString &key)
|
||||
: QProxyStyle(key)
|
||||
{
|
||||
}
|
||||
|
||||
void KAButtonProxyStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
switch(element) {
|
||||
case CE_PushButton:
|
||||
if (const KAButtonStyleOption *btn = qstyleoption_cast<const KAButtonStyleOption *>(option)) {
|
||||
if (KAButtonStyleOption::BT_GROUP == btn->katype) {
|
||||
if (btn->position < KAButtonStyleOption::Begin ||
|
||||
btn->position > KAButtonStyleOption::End)
|
||||
break;
|
||||
proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
|
||||
KAButtonStyleOption subopt = *btn;
|
||||
subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
|
||||
proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
|
||||
return ;
|
||||
} else if (KAButtonStyleOption::BT_TAB == btn->katype) {
|
||||
proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
|
||||
KAButtonStyleOption subopt = *btn;
|
||||
subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
|
||||
proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CE_PushButtonBevel:
|
||||
if (const KAButtonStyleOption *btn = qstyleoption_cast<const KAButtonStyleOption *>(option)) {
|
||||
if (KAButtonStyleOption::BT_GROUP == btn->katype) {
|
||||
if (btn->position < KAButtonStyleOption::Begin ||
|
||||
btn->position > KAButtonStyleOption::End)
|
||||
break;
|
||||
QRect br = btn->rect;
|
||||
int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
|
||||
if (btn->features & QStyleOptionButton::AutoDefaultButton)
|
||||
br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
|
||||
|
||||
KAButtonStyleOption tmpBtn = *btn;
|
||||
tmpBtn.rect = br;
|
||||
proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget);
|
||||
return ;
|
||||
} else if (KAButtonStyleOption::BT_TAB == btn->katype) {
|
||||
QRect br = btn->rect;
|
||||
int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, widget);
|
||||
if (btn->features & QStyleOptionButton::AutoDefaultButton)
|
||||
br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi);
|
||||
|
||||
KAButtonStyleOption tmpBtn = *btn;
|
||||
tmpBtn.rect = br;
|
||||
proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, painter, widget);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CE_PushButtonLabel:
|
||||
{
|
||||
if (const KAButtonStyleOption *button = qstyleoption_cast<const KAButtonStyleOption *>(option)) {
|
||||
if (KAButtonStyleOption::BT_TAB != button->katype)
|
||||
break;
|
||||
const bool enable = button->state & State_Enabled;
|
||||
const bool text = !button->text.isNull();
|
||||
const bool icon = !button->icon.isNull();
|
||||
|
||||
bool isWindowButton = false;
|
||||
bool isWindowColoseButton = false;
|
||||
bool isImportant = false;
|
||||
bool useButtonPalette = false;
|
||||
if (widget) {
|
||||
if (widget->property("isWindowButton").isValid()) {
|
||||
if (widget->property("isWindowButton").toInt() == 0x01)
|
||||
isWindowButton = true;
|
||||
if (widget->property("isWindowButton").toInt() == 0x02)
|
||||
isWindowColoseButton = true;
|
||||
}
|
||||
if (widget->property("isImportant").isValid())
|
||||
isImportant = widget->property("isImportant").toBool();
|
||||
|
||||
if (widget->property("useButtonPalette").isValid())
|
||||
useButtonPalette = widget->property("useButtonPalette").toBool();
|
||||
}
|
||||
|
||||
QRect drawRect = button->rect;
|
||||
int spacing = 8;
|
||||
QStyleOption sub = *option;
|
||||
if (isImportant && !(button->features & QStyleOptionButton::Flat))
|
||||
sub.state = option->state | State_On;
|
||||
else if (isWindowButton || useButtonPalette)
|
||||
sub.state = enable ? State_Enabled : State_None;
|
||||
else
|
||||
sub.state = option->state;
|
||||
|
||||
if (button->features & QStyleOptionButton::HasMenu) {
|
||||
QRect arrowRect;
|
||||
int indicator = proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
|
||||
arrowRect.setRect(drawRect.right() - indicator, drawRect.top() + (drawRect.height() - indicator) / 2, indicator, indicator);
|
||||
arrowRect = visualRect(option->direction, option->rect, arrowRect);
|
||||
if (!text && !icon)
|
||||
spacing = 0;
|
||||
drawRect.setWidth(drawRect.width() - indicator - spacing);
|
||||
drawRect = visualRect(button->direction, button->rect, drawRect);
|
||||
sub.rect = arrowRect;
|
||||
proxy()->drawPrimitive(PE_IndicatorArrowDown, &sub, painter, widget);
|
||||
}
|
||||
|
||||
int tf = Qt::AlignCenter;
|
||||
if (proxy()->styleHint(SH_UnderlineShortcut, button, widget))
|
||||
tf |= Qt::TextShowMnemonic;
|
||||
QPixmap pixmap;
|
||||
if (icon) {
|
||||
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
|
||||
if (mode == QIcon::Normal && button->state & State_HasFocus)
|
||||
mode = QIcon::Active;
|
||||
QIcon::State state = QIcon::Off;
|
||||
if (button->state & State_On)
|
||||
state = QIcon::On;
|
||||
pixmap = button->icon.pixmap(button->iconSize, mode, state);
|
||||
}
|
||||
|
||||
QFontMetrics fm = button->fontMetrics;
|
||||
int textWidth = fm.boundingRect(option->rect, tf, button->text).width() + 2;
|
||||
int iconWidth = icon ? button->iconSize.width() : 0;
|
||||
QRect iconRect, textRect;
|
||||
if (icon && text) {
|
||||
int width = textWidth + spacing + iconWidth;
|
||||
if (width > drawRect.width()) {
|
||||
width = drawRect.width();
|
||||
textWidth = width - spacing - iconWidth;
|
||||
}
|
||||
textRect.setRect(drawRect.x(), drawRect.y(), width, drawRect.height());
|
||||
textRect.moveCenter(drawRect.center());
|
||||
iconRect.setRect(textRect.left(), textRect.top(), iconWidth, textRect.height());
|
||||
textRect.setRect(iconRect.right() + spacing + 1, textRect.y(), textWidth, textRect.height());
|
||||
iconRect = visualRect(option->direction, drawRect, iconRect);
|
||||
textRect = visualRect(option->direction, drawRect, textRect);
|
||||
} else if (icon) {
|
||||
iconRect = drawRect;
|
||||
} else if (text) {
|
||||
textRect = drawRect;
|
||||
}
|
||||
|
||||
if (iconRect.isValid()) {
|
||||
QStyle::drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
|
||||
}
|
||||
|
||||
if (textRect.isValid()) {
|
||||
if (enable) {
|
||||
if (isWindowButton || useButtonPalette) {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::ButtonText);
|
||||
} else {
|
||||
if (isImportant) {
|
||||
if (button->features & QStyleOptionButton::Flat) {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::ButtonText);
|
||||
} else {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::HighlightedText);
|
||||
}
|
||||
if (button->state & (State_MouseOver | State_Sunken | State_On)) {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::HighlightedText);
|
||||
}
|
||||
} else {
|
||||
if (button->state & (State_Sunken | State_On)) {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::Highlight);
|
||||
} else if (button->state & (State_MouseOver)) {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::Highlight);
|
||||
} else {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, true, button->text, QPalette::ButtonText);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
proxy()->drawItemText(painter, textRect, tf, button->palette, false, button->text, QPalette::ButtonText);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QProxyStyle::drawControl(element, option, painter, widget);
|
||||
}
|
||||
|
||||
void KAButtonProxyStyle::drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const
|
||||
{
|
||||
return QProxyStyle::drawItemPixmap(painter, rectangle, alignment, pixmap);
|
||||
}
|
||||
|
||||
void KAButtonProxyStyle::drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole) const
|
||||
{
|
||||
return QProxyStyle::drawItemText(painter, rectangle, alignment, palette, enabled, text, textRole);
|
||||
}
|
||||
|
||||
void KAButtonProxyStyle::drawRoundedRect(QPainter *pa, const QRect &rect, qreal xRadius, qreal yRadius, Corners corners, Qt::SizeMode mode) const
|
||||
{
|
||||
QRectF r = rect.normalized();
|
||||
|
||||
if (r.isNull())
|
||||
return;
|
||||
|
||||
if (mode == Qt::AbsoluteSize) {
|
||||
qreal w = r.width() / 2;
|
||||
qreal h = r.height() / 2;
|
||||
|
||||
if (w == 0) {
|
||||
xRadius = 0;
|
||||
} else {
|
||||
xRadius = 100 * qMin(xRadius, w) / w;
|
||||
}
|
||||
if (h == 0) {
|
||||
yRadius = 0;
|
||||
} else {
|
||||
yRadius = 100 * qMin(yRadius, h) / h;
|
||||
}
|
||||
} else {
|
||||
if (xRadius > 100) // fix ranges
|
||||
xRadius = 100;
|
||||
|
||||
if (yRadius > 100)
|
||||
yRadius = 100;
|
||||
}
|
||||
|
||||
if (xRadius <= 0 || yRadius <= 0) { // add normal rectangle
|
||||
pa->drawRect(r);
|
||||
return;
|
||||
}
|
||||
|
||||
QPainterPath path;
|
||||
qreal x = r.x();
|
||||
qreal y = r.y();
|
||||
qreal w = r.width();
|
||||
qreal h = r.height();
|
||||
qreal rxx2 = w * xRadius / 100;
|
||||
qreal ryy2 = h * yRadius / 100;
|
||||
|
||||
path.arcMoveTo(x, y, rxx2, ryy2, 180);
|
||||
|
||||
if (corners & TopLeftCorner) {
|
||||
path.arcTo(x, y, rxx2, ryy2, 180, -90);
|
||||
} else {
|
||||
path.lineTo(r.topLeft());
|
||||
}
|
||||
|
||||
if (corners & TopRightCorner) {
|
||||
path.arcTo(x + w - rxx2, y, rxx2, ryy2, 90, -90);
|
||||
} else {
|
||||
path.lineTo(r.topRight());
|
||||
}
|
||||
|
||||
if (corners & BottomRightCorner) {
|
||||
path.arcTo(x + w - rxx2, y + h - ryy2, rxx2, ryy2, 0, -90);
|
||||
} else {
|
||||
path.lineTo(r.bottomRight());
|
||||
}
|
||||
|
||||
if (corners & BottomLeftCorner) {
|
||||
path.arcTo(x, y + h - ryy2, rxx2, ryy2, 270, -90);
|
||||
} else {
|
||||
path.lineTo(r.bottomLeft());
|
||||
}
|
||||
|
||||
path.closeSubpath();
|
||||
pa->drawPath(path);
|
||||
}
|
||||
|
||||
//绘制简单的颜色圆角等
|
||||
void KAButtonProxyStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
|
||||
{
|
||||
switch(element) {
|
||||
case PE_PanelButtonCommand:
|
||||
{
|
||||
if (const KAButtonStyleOption *btn = qstyleoption_cast<const KAButtonStyleOption *>(option)) {
|
||||
if (KAButtonStyleOption::BT_GROUP == btn->katype) {
|
||||
if (btn->position < KAButtonStyleOption::Begin ||
|
||||
btn->position > KAButtonStyleOption::End)
|
||||
break;
|
||||
QRect rect = btn->rect;
|
||||
if (!(btn->state & QStyle::State_Enabled)) {
|
||||
if (btn->features & QStyleOptionButton::Flat)
|
||||
return;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(btn->palette.color(QPalette::Disabled, QPalette::Button));
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
switch(btn->position) {
|
||||
case KAButtonStyleOption::Begin:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopLeftCorner | BottomLeftCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::Middle:
|
||||
painter->drawRect(rect);
|
||||
break;
|
||||
case KAButtonStyleOption::End:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopRightCorner | BottomRightCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::OnlyOne:
|
||||
default:
|
||||
painter->drawRoundedRect(rect, 6.0, 6.0);
|
||||
break;
|
||||
}
|
||||
painter->restore();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(btn->state & QStyle::State_AutoRaise) && !(btn->features & QStyleOptionButton::Flat)) {
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(btn->palette.color(QPalette::Button));
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
switch(btn->position) {
|
||||
case KAButtonStyleOption::Begin:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopLeftCorner | BottomLeftCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::Middle:
|
||||
painter->drawRect(rect);
|
||||
break;
|
||||
case KAButtonStyleOption::End:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopRightCorner | BottomRightCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::OnlyOne:
|
||||
default:
|
||||
painter->drawRoundedRect(rect, 6.0, 6.0);
|
||||
break;
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing,true);
|
||||
painter->setPen(Qt::NoPen);
|
||||
if (btn->state & (QStyle::State_Sunken | QStyle::State_On)) {
|
||||
painter->setBrush(btn->palette.color(QPalette::Highlight));
|
||||
} else if (btn->state & QStyle::State_MouseOver) {
|
||||
auto color = btn->palette.color(QPalette::Highlight).lighter(125);
|
||||
painter->setBrush(color);
|
||||
}
|
||||
switch(btn->position) {
|
||||
case KAButtonStyleOption::Begin:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopLeftCorner | BottomLeftCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::Middle:
|
||||
painter->drawRect(rect);
|
||||
break;
|
||||
case KAButtonStyleOption::End:
|
||||
drawRoundedRect(painter, rect, 6.0, 6.0, (Corners)(TopRightCorner | BottomRightCorner));
|
||||
break;
|
||||
case KAButtonStyleOption::OnlyOne:
|
||||
default:
|
||||
painter->drawRoundedRect(rect, 6.0, 6.0);
|
||||
break;
|
||||
}
|
||||
painter->restore();
|
||||
return;
|
||||
} else if (KAButtonStyleOption::BT_TAB == btn->katype) {
|
||||
QRect rect = btn->rect;
|
||||
rect.setY(rect.y()+rect.height()-2);
|
||||
rect.setHeight(2);
|
||||
if (!(btn->state & QStyle::State_Enabled)) {
|
||||
if (btn->features & QStyleOptionButton::Flat)
|
||||
return;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(btn->palette.color(QPalette::Disabled, QPalette::Button));
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
painter->drawRoundedRect(rect, 1.0, 1.0);
|
||||
painter->restore();
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing,true);
|
||||
painter->setPen(Qt::NoPen);
|
||||
if (btn->state & (QStyle::State_Sunken | QStyle::State_On)) {
|
||||
painter->setBrush(btn->palette.color(QPalette::Highlight));
|
||||
} else if (btn->state & QStyle::State_MouseOver) {
|
||||
rect.setHeight(0);
|
||||
auto color = btn->palette.color(QPalette::Highlight).lighter(125);
|
||||
painter->setBrush(color);
|
||||
}
|
||||
painter->drawRoundedRect(rect, 1.0, 1.0);
|
||||
painter->restore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
|
||||
// change control Qsize
|
||||
QSize KAButtonProxyStyle::sizeFromContents(ContentsType ct, const QStyleOption *option,
|
||||
const QSize &size, const QWidget *widget) const
|
||||
{
|
||||
QSize newSize = size;
|
||||
switch (ct) {
|
||||
case CT_PushButton:
|
||||
{
|
||||
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
|
||||
if (!widget->inherits("KATabButton"))
|
||||
break;
|
||||
const bool icon = !button->icon.isNull();
|
||||
const bool text = !button->text.isNull();
|
||||
int w = size.width();
|
||||
int h = size.height();
|
||||
int Margin_Height = 2;
|
||||
int ToolButton_MarginWidth = 2;
|
||||
int Button_MarginWidth = proxy()->pixelMetric(PM_ButtonMargin, option, widget);
|
||||
if (text && !icon && !(button->features & QStyleOptionButton::HasMenu)) {
|
||||
w += Button_MarginWidth * 2;
|
||||
} else {
|
||||
w += ToolButton_MarginWidth * 2;
|
||||
}
|
||||
h += Margin_Height * 2;
|
||||
|
||||
int spacing = 0;
|
||||
if (text && icon)
|
||||
spacing += 4;
|
||||
if (!text && icon)
|
||||
spacing -= 4;
|
||||
if (button->features & QStyleOptionButton::HasMenu) {
|
||||
if (icon || text)
|
||||
spacing += 8;
|
||||
}
|
||||
w += spacing;
|
||||
if (button->features & (QStyleOptionButton::AutoDefaultButton | QStyleOptionButton::DefaultButton)) {
|
||||
int dbw = proxy()->pixelMetric(PM_ButtonDefaultIndicator, option, widget) * 2;
|
||||
w += dbw;
|
||||
h += dbw;
|
||||
}
|
||||
|
||||
newSize.setWidth(w);
|
||||
newSize.setHeight(h);
|
||||
return newSize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QProxyStyle::sizeFromContents(ct, option, size, widget);
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef USMPROXYSTYLE_H
|
||||
#define USMPROXYSTYLE_H
|
||||
|
||||
#include <QProxyStyle>
|
||||
#include <QStyleOption>
|
||||
|
||||
class KAButtonStyleOption : public QStyleOptionButton
|
||||
{
|
||||
public:
|
||||
enum ButtonPosition { OnlyOne = 0x00, Begin = 0x01, Middle = 0x02, End = 0x03 };
|
||||
enum ButtonType { BT_NORMAL = 0x00, BT_GROUP = 0x01, BT_TAB = 0x02 };
|
||||
|
||||
ButtonPosition position;
|
||||
ButtonType katype;
|
||||
KAButtonStyleOption() {}
|
||||
};
|
||||
|
||||
class KAButtonProxyStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
enum Corner {
|
||||
TopLeftCorner = 0x00001,
|
||||
TopRightCorner = 0x00002,
|
||||
BottomLeftCorner = 0x00004,
|
||||
BottomRightCorner = 0x00008
|
||||
};
|
||||
Q_DECLARE_FLAGS(Corners, Corner)
|
||||
|
||||
KAButtonProxyStyle(QStyle *style = nullptr);
|
||||
KAButtonProxyStyle(const QString &key);
|
||||
|
||||
/*!
|
||||
* \brief drawControl
|
||||
* \param element 比如按钮,对应CE枚举类型
|
||||
* \param option
|
||||
* \param painter
|
||||
* \param widget
|
||||
* \details
|
||||
* drawControl用于绘制基本控件元素,它本身一般只负责绘制控件的一部分或者一层。
|
||||
* 如果你想要知道控件具体如何绘制,你需要同时研究这个控件的源码和QStyle中的源码,
|
||||
* 因为它们都有可能改变控件的绘制流程。
|
||||
*
|
||||
* QStyle一般会遵循QCommonStyle的绘制流程,QCommenStyle是大部分主流style的最基类,
|
||||
* 它本身不能完全称之为一个主题,如果你直接使用它,你的控件将不能被正常绘制,因为它有可能只是
|
||||
* 在特定的时候执行了特定却未实现的绘制方法,它更像一个框架或者规范。
|
||||
*/
|
||||
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const;
|
||||
virtual void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const;
|
||||
virtual void drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const;
|
||||
|
||||
/*!
|
||||
* \brief drawPrimitive
|
||||
* \param element 背景绘制,对应PE枚举类型
|
||||
* \param option
|
||||
* \param painter
|
||||
* \param widget
|
||||
* \details
|
||||
* drawPrimitive用于绘制控件背景,比如按钮和菜单的背景,
|
||||
* 我们一般需要判断控件的状态来绘制不同的背景,
|
||||
* 比如按钮的hover和点击效果。
|
||||
*/
|
||||
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const;
|
||||
|
||||
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override;
|
||||
|
||||
private:
|
||||
void drawRoundedRect(QPainter *pa, const QRect &rect, qreal xRadius, qreal yRadius, Corners corners, Qt::SizeMode mode = Qt::AbsoluteSize) const;
|
||||
};
|
||||
|
||||
#endif // USMPROXYSTYLE_H
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kagroupbutton.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStylePainter>
|
||||
#include <QDebug>
|
||||
|
||||
KAGroupButton::KAGroupButton(QWidget *parent)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
mPosition = KAButtonStyleOption::OnlyOne;
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
KAGroupButton::~KAGroupButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void KAGroupButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QStylePainter p(this);
|
||||
KAButtonStyleOption option;
|
||||
initStyleOption(&option);
|
||||
option.position = mPosition;
|
||||
option.katype = KAButtonStyleOption::BT_GROUP;
|
||||
p.drawControl(QStyle::CE_PushButton, option);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KAGROUPBUTTON_H
|
||||
#define KAGROUPBUTTON_H
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
#include "kabuttonproxystyle.h"
|
||||
|
||||
class KAGroupButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KAGroupButton(QWidget *parent = nullptr);
|
||||
virtual ~KAGroupButton();
|
||||
|
||||
inline KAButtonStyleOption::ButtonPosition position()
|
||||
{ return mPosition; }
|
||||
inline void setPosition(KAButtonStyleOption::ButtonPosition pos)
|
||||
{ mPosition = pos; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
KAButtonStyleOption::ButtonPosition mPosition;
|
||||
};
|
||||
|
||||
#endif // KAGROUPBUTTON_H
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kainfotitle.h"
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
|
||||
#define KATITLE_LABEL_WIDTH 4
|
||||
#define KATITLE_LABEL_HEIGHT 14
|
||||
|
||||
KAInfoTitle::KAInfoTitle(QString strTitle, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_strTitle(strTitle)
|
||||
{
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,0);
|
||||
|
||||
m_labelTitle = new QLabel();
|
||||
m_labelTitle->setText(m_strTitle);
|
||||
m_labelTitle->setContentsMargins(0,0,0,0);
|
||||
m_labelTitle->setAlignment(Qt::AlignLeft|Qt::AlignTop);
|
||||
m_mainLayout->addSpacing(KATITLE_LABEL_WIDTH+8);
|
||||
m_mainLayout->addWidget(m_labelTitle, 0, Qt::AlignLeft|Qt::AlignVCenter);
|
||||
|
||||
this->setLayout(m_mainLayout);
|
||||
}
|
||||
|
||||
void KAInfoTitle::setText(QString strTitle)
|
||||
{
|
||||
m_strTitle = strTitle;
|
||||
m_labelTitle->setText(m_strTitle);
|
||||
}
|
||||
|
||||
void KAInfoTitle::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
/*path.addRect(this->rect());
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
painter.setBrush(this->palette().base());
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
painter.drawPath(path);*/
|
||||
// 画小块
|
||||
QRect rectBlue = this->rect();
|
||||
int nX = 0;
|
||||
int nY = 0;
|
||||
int nWidth = 0;
|
||||
int nHeight = 0;
|
||||
if (KATITLE_LABEL_WIDTH > rectBlue.width()) {
|
||||
nX = rectBlue.x();
|
||||
nWidth = rectBlue.width();
|
||||
} else {
|
||||
nX = rectBlue.x();
|
||||
nWidth = KATITLE_LABEL_WIDTH;
|
||||
}
|
||||
if (KATITLE_LABEL_HEIGHT > rectBlue.height()) {
|
||||
nY = rectBlue.y();
|
||||
nHeight = rectBlue.height();
|
||||
} else {
|
||||
nY = rectBlue.y()+(rectBlue.height()-KATITLE_LABEL_HEIGHT)/2;
|
||||
nHeight = KATITLE_LABEL_HEIGHT;
|
||||
}
|
||||
rectBlue.setX(nX);
|
||||
rectBlue.setY(nY);
|
||||
rectBlue.setWidth(nWidth);
|
||||
rectBlue.setHeight(nHeight);
|
||||
QPainterPath path1;
|
||||
path1.addRect(rectBlue);
|
||||
path1.setFillRule(Qt::WindingFill);
|
||||
painter.setBrush(QColor("#3790FA"));
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
painter.drawPath(path1);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KAINFOTITLE_H
|
||||
#define KAINFOTITLE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
class KAInfoTitle : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KAInfoTitle(QString strTitle = "", QWidget *parent = nullptr);
|
||||
void setText(QString strTitle);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QHBoxLayout *m_mainLayout = nullptr;
|
||||
QLabel *m_labelTitle = nullptr;
|
||||
QString m_strTitle;
|
||||
};
|
||||
|
||||
#endif // KAINFOTITLE_H
|
|
@ -0,0 +1,34 @@
|
|||
#include "kalabel.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
KALabel::KALabel(QWidget *parent)
|
||||
: QLabel(parent)
|
||||
{
|
||||
m_strText = "";
|
||||
}
|
||||
|
||||
KALabel::KALabel(QString strText, QWidget *parent)
|
||||
: QLabel(strText, parent)
|
||||
{
|
||||
m_strText = strText;
|
||||
}
|
||||
|
||||
void KALabel::setText(const QString &strText)
|
||||
{
|
||||
m_strText = strText;
|
||||
QLabel::setText(strText);
|
||||
}
|
||||
|
||||
void KALabel::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QString strEText = getElidedText(font(), m_strText, width());
|
||||
if (strEText != m_strText) {
|
||||
QLabel::setText(strEText);
|
||||
setToolTip(m_strText);
|
||||
} else {
|
||||
QLabel::setText(m_strText);
|
||||
setToolTip("");
|
||||
}
|
||||
QLabel::paintEvent(event);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef KALABEL_H
|
||||
#define KALABEL_H
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
class KALabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KALabel(QWidget *parent = nullptr);
|
||||
KALabel(QString strText, QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setText(const QString &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
QString m_strText;
|
||||
};
|
||||
|
||||
#endif // KALABEL_H
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kaslider.h"
|
||||
|
||||
#include <QStyle>
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionSlider>
|
||||
#include <QDebug>
|
||||
#include <QPalette>
|
||||
#include <QPainterPath>
|
||||
|
||||
KASlider::KASlider(QStringList listValues, QWidget *parent)
|
||||
: QSlider(Qt::Horizontal, parent)
|
||||
, m_listValues(listValues)
|
||||
{
|
||||
this->setFixedHeight(64);
|
||||
this->setContentsMargins(0,24,0,0);
|
||||
}
|
||||
|
||||
void KASlider::paintEvent(QPaintEvent *ev)
|
||||
{
|
||||
QSlider::paintEvent(ev);
|
||||
|
||||
auto painter = new QPainter(this);
|
||||
painter->setBrush(QBrush(QColor(QPalette::Base)));
|
||||
|
||||
int nCurPos = (value() - minimum())/tickInterval();
|
||||
if (nCurPos < m_listValues.size()) {
|
||||
auto rect = this->geometry();
|
||||
int numTicks = (maximum() - minimum()) / tickInterval();
|
||||
if (this->orientation() == Qt::Horizontal) {
|
||||
QFontMetrics fontMetrics = QFontMetrics(this->font());
|
||||
QRect fontRect = fontMetrics.boundingRect(m_listValues.at(nCurPos));
|
||||
const int interval = (rect.width() - fontRect.width()) / numTicks;
|
||||
int tickX = 1+(interval*nCurPos);
|
||||
int tickY = rect.height() / 2 - 16;
|
||||
painter->drawText(QPoint(tickX, tickY),
|
||||
this->m_listValues.at(nCurPos));
|
||||
}
|
||||
}
|
||||
painter->end();
|
||||
}
|
||||
|
||||
QStringList KASlider::valueList()
|
||||
{
|
||||
return m_listValues;
|
||||
}
|
||||
|
||||
void KASlider::setValueList(QStringList listValues)
|
||||
{
|
||||
m_listValues = listValues;
|
||||
repaint();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KASLIDER_H
|
||||
#define KASLIDER_H
|
||||
|
||||
#include <QSlider>
|
||||
#include <QStringList>
|
||||
#include <QLabel>
|
||||
|
||||
class KASlider : public QSlider
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KASlider(QStringList listValues, QWidget *parent = nullptr);
|
||||
QStringList valueList();
|
||||
void setValueList(QStringList listValues);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *ev);
|
||||
|
||||
private:
|
||||
QStringList m_listValues;
|
||||
QLabel *m_labelValue = nullptr;
|
||||
};
|
||||
|
||||
#endif // KASLIDER_H
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "katabbar.h"
|
||||
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../../src/commondef.h"
|
||||
#include "kabuttonproxystyle.h"
|
||||
|
||||
KATabBar::KATabBar(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_nCurIndex(-1)
|
||||
, m_fFontSize(DEFAULT_FONT_SIZE)
|
||||
{
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
initUI();
|
||||
initConnections();
|
||||
initStyleTheme();
|
||||
}
|
||||
|
||||
KATabBar::~KATabBar()
|
||||
{
|
||||
if (m_styleSettings) {
|
||||
delete m_styleSettings;
|
||||
m_styleSettings = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
path.addRoundedRect(this->rect(), 6.0, 6.0);
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
painter.setBrush(this->palette().base());
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
painter.drawPath(path);
|
||||
// 画线
|
||||
QPen pen;
|
||||
pen.setWidth(1);
|
||||
pen.setBrush(this->palette().alternateBase());
|
||||
painter.setPen(pen);
|
||||
|
||||
painter.drawLine(this->rect().x(), this->rect().y()+this->rect().height()-2,
|
||||
this->rect().x()+this->rect().width(), this->rect().y()+this->rect().height());
|
||||
}
|
||||
|
||||
void KATabBar::initUI()
|
||||
{
|
||||
m_mainLayout = new QVBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,0);
|
||||
m_mainLayout->setSpacing(0);
|
||||
m_topLayout = new QHBoxLayout();
|
||||
m_topLayout->setContentsMargins(0,0,0,0);
|
||||
m_topLayout->setSpacing(16);
|
||||
m_topMidLayout = new QHBoxLayout();
|
||||
m_topMidLayout->setContentsMargins(0,0,0,0);
|
||||
m_topMidLayout->setSpacing(0);
|
||||
|
||||
m_leftArrowBtn = new QPushButton();
|
||||
m_leftArrowBtn->setIcon(QIcon::fromTheme("pan-start-symbolic"));
|
||||
m_leftArrowBtn->setFlat(true);
|
||||
m_leftArrowBtn->setFixedSize(24, 36);
|
||||
m_leftArrowBtn->setProperty("isWindowButton", 0x01);
|
||||
m_rightArrowBtn = new QPushButton();
|
||||
m_rightArrowBtn->setIcon(QIcon::fromTheme("pan-end-symbolic"));
|
||||
m_rightArrowBtn->setFlat(true);
|
||||
m_rightArrowBtn->setFixedSize(24, 36);
|
||||
m_rightArrowBtn->setProperty("isWindowButton", 0x01);
|
||||
m_topLayout->addWidget(m_leftArrowBtn);
|
||||
|
||||
QWidget *middleWidget = new QWidget();
|
||||
middleWidget->setLayout(m_topMidLayout);
|
||||
m_scrollWidget = new QScrollArea();
|
||||
m_scrollWidget->setAlignment(Qt::AlignTop);
|
||||
m_scrollWidget->setContentsMargins(0, 0, 0, 0);
|
||||
m_scrollWidget->setBackgroundRole(QPalette::Base);
|
||||
m_scrollWidget->setAutoFillBackground(true);
|
||||
m_scrollWidget->setFrameStyle(0);
|
||||
m_scrollWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_scrollWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_scrollWidget->setWidgetResizable(true);
|
||||
m_scrollWidget->setWidget(middleWidget);
|
||||
m_scrollWidget->setFixedHeight(52);
|
||||
m_scrollWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
m_topLayout->addWidget(m_scrollWidget);
|
||||
|
||||
m_topLayout->addWidget(m_rightArrowBtn);
|
||||
|
||||
m_btnGroup = new QButtonGroup(this);
|
||||
m_btnGroup->setExclusive(true);
|
||||
|
||||
m_mainLayout->addLayout(m_topLayout);
|
||||
m_mainLayout->addSpacing(2);
|
||||
|
||||
this->setLayout(m_mainLayout);
|
||||
m_uDirectionBtnWidth = m_leftArrowBtn->width()+m_rightArrowBtn->width()+32;
|
||||
}
|
||||
|
||||
void KATabBar::initConnections()
|
||||
{
|
||||
connect(m_leftArrowBtn, &QPushButton::clicked, this, &KATabBar::onChangeTabPage);
|
||||
connect(m_rightArrowBtn, &QPushButton::clicked, this, &KATabBar::onChangeTabPage);
|
||||
connect(this, &KATabBar::tabIndexPosChange, this, &KATabBar::onTabIndexPosChange);
|
||||
connect(this, &KATabBar::chkSwitchItem, this, &KATabBar::onChkSwitchItem);
|
||||
}
|
||||
|
||||
int KATabBar::addTabButton(KATabButton *tabBtn)
|
||||
{
|
||||
if (!tabBtn)
|
||||
return -1;
|
||||
if (m_btnGroup->id(tabBtn) >= 0)
|
||||
return m_btnGroup->id(tabBtn);
|
||||
tabBtn->setFixedHeight(52);
|
||||
tabBtn->setCheckable(true);
|
||||
tabBtn->setStyle(new KAButtonProxyStyle(m_strStyleName));
|
||||
connect(tabBtn, &QPushButton::clicked, this, &KATabBar::onTabItemClicked);
|
||||
m_btnGroup->addButton(tabBtn, m_btnGroup->buttons().size());
|
||||
m_topMidLayout->addWidget(tabBtn);
|
||||
return m_btnGroup->id(tabBtn);
|
||||
}
|
||||
|
||||
void KATabBar::onChangeTabPage()
|
||||
{
|
||||
QPushButton* btnSender = qobject_cast<QPushButton*>(sender());
|
||||
if (btnSender == m_leftArrowBtn) {
|
||||
QScrollBar *scrollHBar = m_scrollWidget->horizontalScrollBar();
|
||||
scrollHBar->triggerAction(QAbstractSlider::SliderPageStepSub);
|
||||
Q_EMIT chkSwitchItem(-1);
|
||||
} else if (btnSender == m_rightArrowBtn) {
|
||||
QScrollBar *scrollHBar = m_scrollWidget->horizontalScrollBar();
|
||||
scrollHBar->triggerAction(QAbstractSlider::SliderPageStepAdd);
|
||||
Q_EMIT chkSwitchItem(1);
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QWidget::resizeEvent(e);
|
||||
QTimer::singleShot(0, this, [&, this](){
|
||||
Q_EMIT this->tabIndexPosChange(this->m_nCurIndex);
|
||||
});
|
||||
}
|
||||
|
||||
void KATabBar::checkArrowNeedShow()
|
||||
{
|
||||
QScrollBar *scrollHBar = m_scrollWidget->horizontalScrollBar();
|
||||
int nCurValue = scrollHBar->value();
|
||||
int nMaxValue = scrollHBar->maximum();
|
||||
int nMinValue = scrollHBar->minimum();
|
||||
if (nCurValue<=nMinValue) {
|
||||
m_leftArrowBtn->setEnabled(false);
|
||||
} else {
|
||||
m_leftArrowBtn->setEnabled(true);
|
||||
}
|
||||
if (nCurValue>=nMaxValue) {
|
||||
m_rightArrowBtn->setEnabled(false);
|
||||
} else {
|
||||
m_rightArrowBtn->setEnabled(true);
|
||||
}
|
||||
qDebug()<<"min:max:cur:"<<nMinValue<<nMaxValue<<nCurValue;
|
||||
}
|
||||
|
||||
void KATabBar::initStyleTheme()
|
||||
{
|
||||
const QByteArray idd(THEME_QT_SCHEMA);
|
||||
if(QGSettings::isSchemaInstalled(idd)) {
|
||||
m_styleSettings = new QGSettings(idd);
|
||||
}
|
||||
if (m_styleSettings) {
|
||||
connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName") {
|
||||
qDebug()<<"style name changed";
|
||||
auto styleName = m_styleSettings->get(MODE_QT_KEY).toString();
|
||||
|
||||
if (styleName == "ukui-default" || styleName == "ukui-dark" || styleName == "ukui-white"
|
||||
|| styleName == "ukui-black" || styleName == "ukui-light" || styleName == "ukui") {
|
||||
if (styleName == "ukui")
|
||||
styleName = "ukui-default";
|
||||
else if (styleName == "ukui-black")
|
||||
styleName = "ukui-dark";
|
||||
else if (styleName == "ukui-white")
|
||||
styleName = "ukui-light";
|
||||
|
||||
m_strStyleName = styleName;
|
||||
auto listBtn = m_btnGroup->buttons();
|
||||
for (auto btn : listBtn) {
|
||||
btn->setStyle(new KAButtonProxyStyle(m_strStyleName));
|
||||
}
|
||||
}
|
||||
} else if ("systemFont" == key || "systemFontSize" == key) {
|
||||
m_fFontSize = m_styleSettings->get(FONT_SIZE).toString().toFloat();
|
||||
QTimer::singleShot(0, this, [&, this](){
|
||||
Q_EMIT this->tabIndexPosChange(this->m_nCurIndex);
|
||||
});
|
||||
}
|
||||
});
|
||||
auto styleName = m_styleSettings->get(MODE_QT_KEY).toString();
|
||||
if (styleName == "ukui-default" || styleName == "ukui-dark" || styleName == "ukui-white"
|
||||
|| styleName == "ukui-black" || styleName == "ukui-light" || styleName == "ukui") {
|
||||
if (styleName == "ukui")
|
||||
styleName = "ukui-default";
|
||||
else if (styleName == "ukui-black")
|
||||
styleName = "ukui-dark";
|
||||
else if (styleName == "ukui-white")
|
||||
styleName = "ukui-light";
|
||||
|
||||
m_strStyleName = styleName;
|
||||
}
|
||||
m_fFontSize = m_styleSettings->get(FONT_SIZE).toString().toFloat();
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::onChangeTabIndex(int nIndex)
|
||||
{
|
||||
if (m_btnGroup->checkedId() == nIndex ||
|
||||
nIndex < 0 || nIndex >= m_btnGroup->buttons().size())
|
||||
return;
|
||||
auto curBtn = m_btnGroup->button(nIndex);
|
||||
if (curBtn) {
|
||||
curBtn->setChecked(true);
|
||||
m_nCurIndex = nIndex;
|
||||
Q_EMIT tabIndexPosChange(m_nCurIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::onTabItemClicked()
|
||||
{
|
||||
KATabButton* clickedBtn = qobject_cast<KATabButton*>(sender());
|
||||
int nClickedIndex = m_btnGroup->id(clickedBtn);
|
||||
if (nClickedIndex >= 0) {
|
||||
Q_EMIT changeTabIndex(nClickedIndex);
|
||||
clickedBtn->setChecked(true);
|
||||
m_nCurIndex = nClickedIndex;
|
||||
Q_EMIT tabIndexPosChange(m_nCurIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::adjustScroll(int nLength)
|
||||
{
|
||||
QScrollBar *scrollHBar = m_scrollWidget->horizontalScrollBar();
|
||||
qDebug()<<"scroll lenght:"<<nLength;
|
||||
if (nLength > 0) {
|
||||
scrollHBar->setSingleStep(qAbs(nLength));
|
||||
scrollHBar->triggerAction(QAbstractSlider::SliderSingleStepSub);
|
||||
} else {
|
||||
scrollHBar->setSingleStep(qAbs(nLength));
|
||||
scrollHBar->triggerAction(QAbstractSlider::SliderSingleStepAdd);
|
||||
}
|
||||
}
|
||||
|
||||
void KATabBar::onTabIndexPosChange(int nIndex)
|
||||
{
|
||||
KATabButton* curSelectedBtn = qobject_cast<KATabButton*>(m_btnGroup->button(nIndex));
|
||||
if (curSelectedBtn) {
|
||||
QRect rectSelected = curSelectedBtn->geometry();
|
||||
QRect rectParentParent = this->geometry();
|
||||
QRect rectParent = ((QWidget*)(curSelectedBtn->parent()))->geometry();
|
||||
int nHideLeft = rectSelected.x()+rectParent.x();
|
||||
if (nHideLeft < 0 && qAbs(nHideLeft) < rectSelected.width()) {
|
||||
qDebug()<<"Selected btn left hide, should move to right:"<<nHideLeft;
|
||||
adjustScroll(qAbs(nHideLeft));
|
||||
} else {
|
||||
int nHideRight = nHideLeft + rectSelected.width()-(rectParentParent.width()-m_uDirectionBtnWidth);
|
||||
if (nHideRight > 0 && nHideRight < rectSelected.width()) {
|
||||
qDebug()<<"Selected btn right hide, should move to left:"<<nHideRight;
|
||||
adjustScroll(-nHideRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
checkArrowNeedShow();
|
||||
}
|
||||
|
||||
void KATabBar::onChkSwitchItem(int nDirection)
|
||||
{
|
||||
KATabButton* curSelectedBtn = qobject_cast<KATabButton*>(m_btnGroup->button(m_nCurIndex));
|
||||
if (curSelectedBtn) {
|
||||
QRect rectSelected = curSelectedBtn->geometry();
|
||||
QRect rectParentParent = this->geometry();
|
||||
QRect rectParent = ((QWidget*)(curSelectedBtn->parent()))->geometry();
|
||||
int nHideLeft = rectSelected.x()+rectParent.x();
|
||||
int nNewIndex = -1;
|
||||
if (nHideLeft < 0) {
|
||||
if (nDirection > 0) { // 向右切页
|
||||
for (auto *btn : m_btnGroup->buttons()) {
|
||||
KATabButton* tabBtn = qobject_cast<KATabButton*>(btn);
|
||||
if (tabBtn) {
|
||||
if (tabBtn->geometry().x()+rectParent.x() >= 0) {
|
||||
nNewIndex = m_btnGroup->id(tabBtn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int nHideRight = nHideLeft + rectSelected.width()-(rectParentParent.width()-m_uDirectionBtnWidth);
|
||||
if (nHideRight > 0) {
|
||||
if (nDirection < 0) { // 向左切页
|
||||
QList<QAbstractButton*>::reverse_iterator ritBtn = m_btnGroup->buttons().rbegin();
|
||||
for ( ; ritBtn != m_btnGroup->buttons().rend(); ritBtn++) {
|
||||
KATabButton* tabBtn = qobject_cast<KATabButton*>(*ritBtn);
|
||||
if (tabBtn) {
|
||||
int nLeftWidth = tabBtn->geometry().x()+tabBtn->geometry().width()+rectParent.x();
|
||||
int nMaxWidth = rectParentParent.width()-m_uDirectionBtnWidth;
|
||||
if (nLeftWidth <= nMaxWidth) {
|
||||
nNewIndex = m_btnGroup->id(tabBtn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nNewIndex >= 0) {
|
||||
KATabButton* newSelectedBtn = qobject_cast<KATabButton*>(m_btnGroup->button(nNewIndex));
|
||||
QTimer::singleShot(0, this, [&, this, newSelectedBtn](){
|
||||
Q_EMIT newSelectedBtn->clicked(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
checkArrowNeedShow();
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KATABBAR_H
|
||||
#define KATABBAR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QScrollArea>
|
||||
#include <qgsettings.h>
|
||||
|
||||
#include "katabbutton.h"
|
||||
|
||||
class KATabBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KATabBar(QWidget *parent = nullptr);
|
||||
virtual ~KATabBar();
|
||||
|
||||
void initUI();
|
||||
void initConnections();
|
||||
|
||||
int addTabButton(KATabButton *tabBtn);
|
||||
int getCurIndex();
|
||||
|
||||
public slots:
|
||||
void onChangeTabPage();
|
||||
void checkArrowNeedShow();
|
||||
void onChangeTabIndex(int nIndex);
|
||||
void onTabItemClicked();
|
||||
void onTabIndexPosChange(int nIndex);
|
||||
void onChkSwitchItem(int nDirection);
|
||||
|
||||
signals:
|
||||
void changeTabIndex(int nIndex);
|
||||
void tabIndexPosChange(int nIndex);
|
||||
void chkSwitchItem(int nDirection);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private:
|
||||
void initStyleTheme();
|
||||
void adjustScroll(int nLength);
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_mainLayout = nullptr;
|
||||
QHBoxLayout *m_topLayout = nullptr;
|
||||
QHBoxLayout *m_topMidLayout = nullptr;
|
||||
QPushButton *m_leftArrowBtn = nullptr;
|
||||
QPushButton *m_rightArrowBtn = nullptr;
|
||||
|
||||
QButtonGroup *m_btnGroup = nullptr;
|
||||
QScrollArea *m_scrollWidget = nullptr;
|
||||
QGSettings *m_styleSettings = nullptr;
|
||||
|
||||
QString m_strStyleName;
|
||||
int m_nCurIndex;
|
||||
unsigned m_uDirectionBtnWidth = 0;
|
||||
float m_fFontSize = 0;
|
||||
};
|
||||
|
||||
#endif // KATABBAR_H
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "katabbutton.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStylePainter>
|
||||
#include <QDebug>
|
||||
|
||||
#include "kabuttonproxystyle.h"
|
||||
|
||||
KATabButton::KATabButton(QWidget *parent)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
}
|
||||
|
||||
void KATabButton::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
path.addRect(this->rect());
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
painter.setBrush(this->palette().base());
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
painter.drawPath(path);
|
||||
|
||||
QStylePainter p(this);
|
||||
KAButtonStyleOption option;
|
||||
initStyleOption(&option);
|
||||
option.katype = KAButtonStyleOption::BT_TAB;
|
||||
p.drawControl(QStyle::CE_PushButton, option);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KATABBUTTON_H
|
||||
#define KATABBUTTON_H
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QStyleOptionButton>
|
||||
|
||||
class KATabButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KATabButton(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
};
|
||||
|
||||
#endif // KATABBUTTON_H
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kdriveinfoitem.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QIcon>
|
||||
#include <QPaintEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
#include <QFileInfo>
|
||||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../../src/commondef.h"
|
||||
|
||||
KDriveInfoItem::KDriveInfoItem(QString strTitle, QString strIcon, QString strDriveName, QString strDriveVer, bool isOdd, QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
m_strTitle = strTitle;
|
||||
m_strIcon = strIcon;
|
||||
m_strDriveName = strDriveName;
|
||||
m_strDriveVersion = strDriveVer;
|
||||
m_isOdd = isOdd;
|
||||
m_alternateBase = palette().alternateBase().color();
|
||||
initUI();
|
||||
}
|
||||
|
||||
KDriveInfoItem::~KDriveInfoItem()
|
||||
{
|
||||
if (m_styleSettings) {
|
||||
delete m_styleSettings;
|
||||
m_styleSettings = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void KDriveInfoItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
path.addRoundedRect(this->rect(), 6, 6);
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
if(m_isOdd) {
|
||||
painter.setBrush(this->palette().base());
|
||||
} else {
|
||||
QBrush brush = this->palette().alternateBase();
|
||||
brush.setColor(m_alternateBase);
|
||||
painter.setBrush(brush);
|
||||
}
|
||||
painter.drawPath(path);
|
||||
}
|
||||
|
||||
void KDriveInfoItem::initUI()
|
||||
{
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,0);
|
||||
m_mainLayout->setSpacing(0);
|
||||
//m_mainLayout->setAlignment(Qt::AlignTop);
|
||||
m_driveInfoLayout = new QVBoxLayout();
|
||||
m_driveInfoLayout->setContentsMargins(0,0,0,0);
|
||||
m_driveInfoLayout->setSpacing(0);
|
||||
//m_driveInfoLayout->setAlignment(Qt::AlignTop);
|
||||
|
||||
m_mainLayout->addSpacing(22);
|
||||
|
||||
if (!m_strIcon.isEmpty()) {
|
||||
m_labelIcon = new QLabel();
|
||||
QIcon icon;
|
||||
if (m_strIcon.contains("/")) {
|
||||
QFileInfo fileInfo(m_strIcon);
|
||||
if (fileInfo.exists()) {
|
||||
icon = QIcon(m_strIcon);
|
||||
}
|
||||
} else {
|
||||
icon = QIcon::fromTheme(m_strIcon);
|
||||
}
|
||||
m_labelIcon->setPixmap(icon.pixmap(16,16));
|
||||
m_mainLayout->addWidget(m_labelIcon, 0, Qt::AlignHCenter);
|
||||
m_mainLayout->addSpacing(12);
|
||||
}
|
||||
m_labelTitle = new QLabel();
|
||||
m_labelTitle->setText(m_strTitle);
|
||||
m_mainLayout->addWidget(m_labelTitle, 2, Qt::AlignLeft);
|
||||
m_labelDriveName = new QLabel();
|
||||
m_labelDriveName->setText(m_strDriveName);
|
||||
m_labelDriveName->setWordWrap(true);
|
||||
m_driveInfoLayout->addWidget(m_labelDriveName);
|
||||
m_labelDriveVersion = new QLabel();
|
||||
m_labelDriveVersion->setText(m_strDriveVersion);
|
||||
m_labelDriveVersion->setWordWrap(true);
|
||||
if (m_strDriveVersion.isEmpty()) {
|
||||
m_labelDriveVersion->hide();
|
||||
}
|
||||
m_driveInfoLayout->addWidget(m_labelDriveVersion);
|
||||
m_mainLayout->addLayout(m_driveInfoLayout, 6);
|
||||
m_mainLayout->addStretch();
|
||||
|
||||
m_rkeyMenu = new QMenu(this);
|
||||
QAction *copyAction = new QAction(QIcon::fromTheme("edit-copy-symbolic"), tr("Copy"), this);
|
||||
connect(copyAction, &QAction::triggered, this, &KDriveInfoItem::onCopyContent);
|
||||
m_rkeyMenu->addAction(copyAction);
|
||||
|
||||
this->setLayout(m_mainLayout);
|
||||
initStyleTheme();
|
||||
}
|
||||
|
||||
void KDriveInfoItem::initStyleTheme()
|
||||
{
|
||||
const QByteArray idd(THEME_QT_SCHEMA);
|
||||
if(QGSettings::isSchemaInstalled(idd)) {
|
||||
m_styleSettings = new QGSettings(idd);
|
||||
}
|
||||
if (m_styleSettings) {
|
||||
connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName") {
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KDriveInfoItem::updateDriveInfo(QString strDriveName, QString strDriveVersion)
|
||||
{
|
||||
if (m_labelDriveName)
|
||||
m_labelDriveName->setText(strDriveName);
|
||||
if (m_labelDriveVersion) {
|
||||
m_labelDriveVersion->setText(strDriveVersion);
|
||||
if (m_strDriveVersion.isEmpty()) {
|
||||
m_labelDriveVersion->hide();
|
||||
} else {
|
||||
m_labelDriveVersion->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KDriveInfoItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
m_rkeyMenu->popup(event->globalPos());
|
||||
}
|
||||
QFrame::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void KDriveInfoItem::onCopyContent()
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
QString strCopy = m_strTitle+":"+m_strDriveName;
|
||||
if (!m_strDriveVersion.isEmpty()) {
|
||||
strCopy += " "+m_strDriveVersion;
|
||||
}
|
||||
clipboard->setText(strCopy);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KDRIVEINFOITEM_H
|
||||
#define KDRIVEINFOITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFrame>
|
||||
#include <QColor>
|
||||
#include <qgsettings.h>
|
||||
#include <QMenu>
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
class QHBoxLayout;
|
||||
|
||||
class KDriveInfoItem : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KDriveInfoItem(QString strTitle, QString strIcon, QString strDriveName, QString strDriveVer, bool isOdd, QWidget *parent = nullptr);
|
||||
virtual ~KDriveInfoItem();
|
||||
|
||||
void initUI();
|
||||
void updateDriveInfo(QString strDriveName, QString strDriveVer);
|
||||
|
||||
public slots:
|
||||
void onCopyContent();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
void initStyleTheme();
|
||||
|
||||
private:
|
||||
QHBoxLayout *m_mainLayout = nullptr;
|
||||
QVBoxLayout *m_driveInfoLayout = nullptr;
|
||||
|
||||
QLabel *m_labelIcon = nullptr;
|
||||
QLabel *m_labelTitle = nullptr;
|
||||
QLabel *m_labelDriveName = nullptr;
|
||||
QLabel *m_labelDriveVersion = nullptr;
|
||||
|
||||
QString m_strTitle;
|
||||
QString m_strIcon;
|
||||
QString m_strDriveName;
|
||||
QString m_strDriveVersion;
|
||||
|
||||
bool m_isOdd = false;
|
||||
QGSettings *m_styleSettings = nullptr;
|
||||
QColor m_alternateBase;
|
||||
QMenu *m_rkeyMenu = nullptr;
|
||||
};
|
||||
|
||||
#endif // KDRIVEINFOITEM_H
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "kinfolistitem.h"
|
||||
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QIcon>
|
||||
#include <QPaintEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
#include <QFileInfo>
|
||||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#include "../../src/commondef.h"
|
||||
|
||||
KInfoListItem::KInfoListItem(QString strTitle, QString strIcon, QString strDetail, bool isOdd, QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
m_strTitle = strTitle;
|
||||
m_strIcon = strIcon;
|
||||
m_strDetail = strDetail;
|
||||
m_isOdd = isOdd;
|
||||
m_alternateBase = palette().alternateBase().color();
|
||||
initUI();
|
||||
}
|
||||
|
||||
KInfoListItem::~KInfoListItem()
|
||||
{
|
||||
if (m_styleSettings) {
|
||||
delete m_styleSettings;
|
||||
m_styleSettings = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void KInfoListItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
path.addRoundedRect(this->rect(), 6, 6);
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
if(m_isOdd) {
|
||||
painter.setBrush(this->palette().base());
|
||||
} else {
|
||||
QBrush brush = this->palette().alternateBase();
|
||||
brush.setColor(m_alternateBase);
|
||||
painter.setBrush(brush);
|
||||
}
|
||||
painter.drawPath(path);
|
||||
}
|
||||
|
||||
void KInfoListItem::initUI()
|
||||
{
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,0);
|
||||
m_mainLayout->setSpacing(0);
|
||||
|
||||
m_mainLayout->addSpacing(22);
|
||||
|
||||
if (!m_strIcon.isEmpty()) {
|
||||
m_labelIcon = new QLabel();
|
||||
QIcon icon;
|
||||
if (m_strIcon.contains("/")) {
|
||||
QFileInfo fileInfo(m_strIcon);
|
||||
if (fileInfo.exists()) {
|
||||
icon = QIcon(m_strIcon);
|
||||
}
|
||||
} else {
|
||||
icon = QIcon::fromTheme(m_strIcon);
|
||||
}
|
||||
m_labelIcon->setPixmap(icon.pixmap(16,16));
|
||||
m_mainLayout->addWidget(m_labelIcon, 0, Qt::AlignHCenter);
|
||||
m_mainLayout->addSpacing(12);
|
||||
}
|
||||
m_labelTitle = new KALabel();
|
||||
m_labelTitle->setText(m_strTitle);
|
||||
m_labelTitle->setFixedWidth(150);
|
||||
m_mainLayout->addWidget(m_labelTitle, 0, Qt::AlignLeft);
|
||||
m_labelDetail = new KALabel();
|
||||
m_labelDetail->setText(m_strDetail);
|
||||
m_labelDetail->setFixedWidth(460);
|
||||
//m_labelDetail->setWordWrap(true);
|
||||
m_mainLayout->addWidget(m_labelDetail, 0, Qt::AlignLeft);
|
||||
m_mainLayout->addStretch();
|
||||
|
||||
m_rkeyMenu = new QMenu(this);
|
||||
QAction *copyAction = new QAction(QIcon::fromTheme("edit-copy-symbolic"), tr("Copy"), this);
|
||||
connect(copyAction, &QAction::triggered, this, &KInfoListItem::onCopyContent);
|
||||
m_rkeyMenu->addAction(copyAction);
|
||||
|
||||
this->setLayout(m_mainLayout);
|
||||
initStyleTheme();
|
||||
}
|
||||
|
||||
void KInfoListItem::initStyleTheme()
|
||||
{
|
||||
const QByteArray idd(THEME_QT_SCHEMA);
|
||||
if(QGSettings::isSchemaInstalled(idd)) {
|
||||
m_styleSettings = new QGSettings(idd);
|
||||
}
|
||||
if (m_styleSettings) {
|
||||
connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName") {
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KInfoListItem::updateDetailInfo(QString strDetail)
|
||||
{
|
||||
if (m_labelDetail)
|
||||
m_labelDetail->setText(strDetail);
|
||||
}
|
||||
|
||||
void KInfoListItem::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
m_rkeyMenu->popup(event->globalPos());
|
||||
}
|
||||
QFrame::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void KInfoListItem::onCopyContent()
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setText(m_strTitle+":"+m_strDetail);
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KINFOLISTITEM_H
|
||||
#define KINFOLISTITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFrame>
|
||||
#include <QColor>
|
||||
#include <qgsettings.h>
|
||||
#include <QMenu>
|
||||
#include "kalabel.h"
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
class QHBoxLayout;
|
||||
|
||||
class KInfoListItem : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KInfoListItem(QString strTitle, QString strIcon, QString strDetail, bool isOdd, QWidget *parent = nullptr);
|
||||
virtual ~KInfoListItem();
|
||||
|
||||
void initUI();
|
||||
void updateDetailInfo(QString strDetail);
|
||||
|
||||
public slots:
|
||||
void onCopyContent();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
private:
|
||||
void initStyleTheme();
|
||||
|
||||
private:
|
||||
QHBoxLayout *m_mainLayout = nullptr;
|
||||
|
||||
QLabel *m_labelIcon = nullptr;
|
||||
KALabel *m_labelTitle = nullptr;
|
||||
KALabel *m_labelDetail = nullptr;
|
||||
|
||||
QString m_strTitle;
|
||||
QString m_strIcon;
|
||||
QString m_strDetail;
|
||||
|
||||
bool m_isOdd = false;
|
||||
QGSettings *m_styleSettings = nullptr;
|
||||
QColor m_alternateBase;
|
||||
QMenu *m_rkeyMenu = nullptr;
|
||||
};
|
||||
|
||||
#endif // KINFOLISTITEM_H
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "loadingwidget.h"
|
||||
|
||||
LoadingWidget::LoadingWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
initUI();
|
||||
}
|
||||
|
||||
void LoadingWidget::initUI()
|
||||
{
|
||||
m_hLayout = new QHBoxLayout();
|
||||
m_hLayout->setContentsMargins(0,0,0,0);
|
||||
m_hLayout->setSpacing(0);
|
||||
m_vLayout = new QVBoxLayout();
|
||||
m_vLayout->setContentsMargins(0,0,0,0);
|
||||
m_vLayout->setSpacing(0);
|
||||
|
||||
m_labelLoadIcon = new QLabel();
|
||||
QPixmap pixmap;
|
||||
pixmap.load(":/imgres/img_res/ukui-occupation-map.svg");
|
||||
pixmap.scaled(290,262);
|
||||
m_labelLoadIcon->setPixmap(pixmap);
|
||||
|
||||
m_labelLoadText = new QLabel();
|
||||
m_labelLoadText->setText(tr("Scanning, please wait"));
|
||||
|
||||
m_vLayout->addStretch(40);
|
||||
m_vLayout->addWidget(m_labelLoadIcon, 0, Qt::AlignHCenter);
|
||||
m_vLayout->addSpacing(10);
|
||||
m_vLayout->addWidget(m_labelLoadText, 0, Qt::AlignHCenter);
|
||||
m_vLayout->addStretch(55);
|
||||
|
||||
m_hLayout->addLayout(m_vLayout);
|
||||
this->setLayout(m_hLayout);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOADINGWIDGET_H
|
||||
#define LOADINGWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
class LoadingWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LoadingWidget(QWidget *parent = nullptr);
|
||||
|
||||
void initUI();
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_vLayout = nullptr;
|
||||
QHBoxLayout *m_hLayout = nullptr;
|
||||
QLabel *m_labelLoadIcon = nullptr;
|
||||
QLabel *m_labelLoadText = nullptr;
|
||||
};
|
||||
|
||||
#endif // LOADINGWIDGET_H
|
|
@ -0,0 +1,40 @@
|
|||
kylin-assistant
|
||||
================
|
||||
|
||||
Attention
|
||||
=========
|
||||
It supports unity and mate for Ubuntu/Ubuntu Kylin.
|
||||
|
||||
Depends
|
||||
=======
|
||||
debhelper (>= 9),libqt5charts5-dev,qtbase5-dev (>= 5.1),libqt5svg5-dev,libqt5charts5-dev,qt5-qmake,qtscript5-dev,qttools5-dev-tools,libgsettings-qt-dev,pkg-config,libglib2.0-dev (>= 2.46.0),libgtop2-dev,libkf5windowsystem-dev,libqt5x11extras5-dev,libxrandr-dev,libudev-dev,libukui-log4qt-dev,libsdl2-dev,libepoxy-dev
|
||||
|
||||
GitHub
|
||||
=======
|
||||
https://github.com/KylinAppCenter/kylin-assistant
|
||||
|
||||
Internationalization
|
||||
=======
|
||||
lupdate kylin-assistant.pro
|
||||
linguist kylin-assistant_zh_CN.ts
|
||||
lrelease kylin-assistant.pro
|
||||
|
||||
Python Internationalization
|
||||
=======
|
||||
xgettext -k_ -o kylin-assistant.pot cpuinfo.py
|
||||
kylin-assistant.pot:修改charset为utf-8
|
||||
cp kylin-assistant.pot kylin-assistant.po
|
||||
msgfmt -o kylin-assistant.mo kylin-assistant.po
|
||||
(sudo cp kylin-assistant.mo /usr/share/locale/zh_CN/LC_MESSAGES/)
|
||||
|
||||
|
||||
|
||||
|
||||
FT Version:
|
||||
changelog like this:
|
||||
youker-assistant (3.0.2-0) v101; urgency=medium
|
||||
|
||||
DEBUG:
|
||||
gdb python
|
||||
set args kasystemdbusmain.py
|
||||
run
|
|
@ -0,0 +1,6 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
HEADERS += \
|
||||
$$PWD/utils.h
|
||||
SOURCES += \
|
||||
$$PWD/utils.cpp
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QProcess>
|
||||
|
||||
QString getElidedText(QFont font, QString str, int MaxWidth)
|
||||
{
|
||||
if(str.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
QFontMetrics fontWidth(font);
|
||||
|
||||
//计算字符串宽度
|
||||
int width = fontWidth.width(str);
|
||||
|
||||
//当字符串宽度大于最大宽度时进行转换
|
||||
if(width >= MaxWidth) {
|
||||
//右部显示省略号
|
||||
str = fontWidth.elidedText(str, Qt::ElideRight, MaxWidth);
|
||||
}
|
||||
//返回处理后的字符串
|
||||
return str;
|
||||
}
|
||||
|
||||
void centerToScreen(QWidget* widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
QDesktopWidget* m = QApplication::desktop();
|
||||
QRect desk_rect = m->screenGeometry(widget);
|
||||
int desk_x = desk_rect.width();
|
||||
int desk_y = desk_rect.height();
|
||||
int x = widget->width();
|
||||
int y = widget->height();
|
||||
widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top());
|
||||
}
|
||||
|
||||
// 获取应用程序版本
|
||||
QString getKAVersion()
|
||||
{
|
||||
QString versionText;
|
||||
QProcess proc;
|
||||
QStringList options;
|
||||
options << "-l" << "|" << "grep" << "youker-assistant";
|
||||
proc.start("dpkg", options);
|
||||
proc.waitForFinished();
|
||||
QString dpkgInfo = proc.readAll();
|
||||
QStringList infoList = dpkgInfo.split("\n");
|
||||
for (int n = 0; n < infoList.size(); n++) {
|
||||
QString strInfoLine = infoList[n];
|
||||
if (strInfoLine.contains("youker-assistant")) {
|
||||
QStringList lineInfoList = strInfoLine.split(QRegExp("[\\s]+"));
|
||||
if (lineInfoList.size() >= 3) {
|
||||
versionText = lineInfoList[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return versionText;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QFont>
|
||||
|
||||
QString getElidedText(QFont font, QString str, int MaxWidth);
|
||||
|
||||
void centerToScreen(QWidget* widget);
|
||||
|
||||
// 获取应用程序版本
|
||||
QString getKAVersion();
|
||||
|
||||
#endif // UTILS_H
|
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 71 KiB |
|
@ -0,0 +1,50 @@
|
|||
# ToolKit
|
||||
## Overview
|
||||
ToolKit provides some extended functions and users can query the hardware details of the current computer. The main interface as shown in Fig 1.
|
||||
|
||||
![Fig 1 ToolKit-big](image/1.png)
|
||||
<br>
|
||||
|
||||
## MachineInformation
|
||||
|
||||
As shown in Figure 2, the general information of the whole machine is displayed.
|
||||
|
||||
![Fig 2 Machine Information-big](image/1.png)
|
||||
<br>
|
||||
|
||||
## HardwareParameters
|
||||
|
||||
1) Processor: displays details of the computer's processor.
|
||||
|
||||
![Fig 3 Processor-big](image/2.png)
|
||||
|
||||
2)Memory: displays details of the computer's memory.
|
||||
|
||||
![Fig 4 Memory-big](image/3.png)
|
||||
|
||||
3)Click other items to switch to the hardware details tab.
|
||||
|
||||
![Fig 5 MotherBoard-big](image/4.png)
|
||||
|
||||
<br>
|
||||
|
||||
## HardwareMonitoring
|
||||
|
||||
1)Equipment monitoring, users can view the temperature and utilization of hardware equipment.
|
||||
|
||||
![Fig 6 Device Monitor-big](image/5.png)
|
||||
|
||||
2)CPU frequency modulation, user can set CPU management policy.
|
||||
|
||||
(Note: CPU management policies may be different under different machines, the following content is for reference only)
|
||||
|
||||
![Fig 7 CPU FM-big](image/6.png)
|
||||
<br>
|
||||
|
||||
## DriveManager
|
||||
|
||||
The interface is shown in Figure 9, which displays each driver information in the computer.
|
||||
|
||||
![Fig 9 Drive Manager-big](image/8.png)
|
||||
<br>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 47 KiB |
|
@ -0,0 +1,52 @@
|
|||
# 工具箱
|
||||
## 概 述
|
||||
工具箱提供了整机信息,硬件参数,硬件监测等功能。主界面如图1所示。
|
||||
|
||||
![图 1 工具箱-big](image/1.png)
|
||||
<br>
|
||||
|
||||
## 整机信息
|
||||
|
||||
如图2所示,展示整机的概要信息。
|
||||
|
||||
![图 2 整机信息-big](image/1.png)
|
||||
<br>
|
||||
|
||||
## 硬件参数
|
||||
|
||||
1)处理器:显示计算机处理器的详细信息。
|
||||
|
||||
![图 3 处理器-big](image/2.png)
|
||||
|
||||
2)内存:显示计算机内存的详细信息。
|
||||
|
||||
![图 4 内存-big](image/3.png)
|
||||
|
||||
3)点击其他项目,切换到该硬件的详细信息标签页。
|
||||
|
||||
![图 5 主板-big](image/4.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 硬件监测
|
||||
1)设备监测,用户可查看硬件设备温度和使用率。
|
||||
|
||||
![图 6 设备监测-big](image/5.png)
|
||||
|
||||
2)CPU调频,用户可设置CPU管理策略。
|
||||
|
||||
(注意:不同机器下CPU管理策略可能有差异,以下内容仅供参考)
|
||||
|
||||
![图 7 CPU调频-big](image/6.png)
|
||||
|
||||
自定义模式如图8所示。
|
||||
|
||||
![图 8 自定义模式](image/7.png)
|
||||
<br>
|
||||
|
||||
## 驱动管理
|
||||
界面如图9所示,显示了计算机中的各个驱动信息。
|
||||
|
||||
![图 9 驱动管理-big](image/8.png)
|
||||
<br>
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATAWORKER_H
|
||||
#define DATAWORKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
|
||||
class DataWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~DataWorker();
|
||||
static DataWorker* getInstance();
|
||||
|
||||
// 连接被动更新信号
|
||||
void connectCpuFMInfoSignal(bool bConnect = true); //CPU调频
|
||||
void connectDevMonitorInfoSignal(bool bConnect = true); //设备监测
|
||||
void connectHDInfoSignal(bool bConnect = true); //硬盘
|
||||
void connectMemInfoSignal(bool bConnect = true); //内存
|
||||
void connectProcInfoSignal(bool bConnect = true); //处理器
|
||||
void connectMBInfoSignal(bool bConnect = true); //主板
|
||||
void connectNWInfoSignal(bool bConnect = true); //网卡
|
||||
void connectVCInfoSignal(bool bConnect = true); //声卡
|
||||
void connectGSInfoSignal(bool bConnect = true); //显卡
|
||||
void connectBLInfoSignal(bool bConnect = true); //蓝牙
|
||||
void connectKBInfoSignal(bool bConnect = true); //键盘
|
||||
void connectMSInfoSignal(bool bConnect = true); //鼠标
|
||||
void connectMNInfoSignal(bool bConnect = true); //显示
|
||||
void connectCDInfoSignal(bool bConnect = true); //光驱
|
||||
void connectBTInfoSignal(bool bConnect = true); //电池
|
||||
void connectFAInfoSignal(bool bConnect = true); //风扇
|
||||
void connectCAInfoSignal(bool bConnect = true); //摄像头
|
||||
void connectOutlineSignal(bool bConnect = true); //整机概要信息
|
||||
void connectSysInfoSignal(bool bConnect = true); //系统概要信息
|
||||
void connectHardwareInfoSignal(bool bConnect = true); //硬件参数信息
|
||||
void connectLshwInfoSignal(bool bConnect = true); //刷新lshw信息
|
||||
|
||||
bool getCpuTempEnable();
|
||||
bool getCpuFanEnable();
|
||||
bool getCpuFMEnable();
|
||||
bool updateLshwInfo(bool bForceUpdate = true); //更新lshw信息
|
||||
bool exitSystemDaemonDbus(); //退出dbus
|
||||
bool exitSessionDaemonDbus(); //退出sessiondbus
|
||||
|
||||
public slots:
|
||||
// 异步获取接口
|
||||
void getCpuFMInfo();
|
||||
void onAsyncGetCpuFMInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void setCpuFMInfo(QString strInfoJson);
|
||||
void getDevMonitorInfo();
|
||||
void onAsyncDevMonitorInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void getHardwareInfo();
|
||||
void onAsyncHardwareInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void getHardDiskInfo();
|
||||
void onAsyncHardDiskInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void getMemoryInfo();
|
||||
void onAsyncMemoryInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void getProcessorInfo();
|
||||
void onAsyncProcessorInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void getMotherBoardInfo();
|
||||
void onAsyncMotherBoard(QDBusPendingCallWatcher* callWatcher);
|
||||
void getNetworkCardInfo();
|
||||
void onAsyncNetworkCard(QDBusPendingCallWatcher* callWatcher);
|
||||
void getVoiceCardInfo();
|
||||
void onAsyncVoiceCard(QDBusPendingCallWatcher* callWatcher);
|
||||
QString getVoiceCardExtInfoSync();
|
||||
void getVoiceCardExtInfo();
|
||||
void onAsyncVoiceCardExt(QDBusPendingCallWatcher* callWatcher);
|
||||
void getGraphicsCardInfo();
|
||||
void onAsyncGraphicsCard(QDBusPendingCallWatcher* callWatcher);
|
||||
void getBluetoothInfo();
|
||||
void onAsyncBluetooth(QDBusPendingCallWatcher* callWatcher);
|
||||
void getKeyboardInfo();
|
||||
void onAsyncKeyboard(QDBusPendingCallWatcher* callWatcher);
|
||||
void getMouseInfo();
|
||||
void onAsyncMouse(QDBusPendingCallWatcher* callWatcher);
|
||||
void getMonitorInfo(bool bUpdate = true);
|
||||
void onAsyncMonitor(QDBusPendingCallWatcher* callWatcher);
|
||||
void getCDDriveInfo();
|
||||
void onAsyncCDDrive(QDBusPendingCallWatcher* callWatcher);
|
||||
void getBatteryInfo();
|
||||
void onAsyncBattery(QDBusPendingCallWatcher* callWatcher);
|
||||
void getFanInfo();
|
||||
void onAsyncFan(QDBusPendingCallWatcher* callWatcher);
|
||||
void getCameraInfo();
|
||||
void onAsyncCamera(QDBusPendingCallWatcher* callWatcher);
|
||||
void getOutline();
|
||||
void onAsyncOutline(QDBusPendingCallWatcher* callWatcher);
|
||||
void getSysInfo();
|
||||
void onAsyncSysInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
void onAsyncLshwInfo(QDBusPendingCallWatcher* callWatcher);
|
||||
|
||||
signals:
|
||||
//异步获取返回信息信号
|
||||
void updateCpuFMInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateDevMonitorInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateHardwareInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateHardDiskInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateMemoryInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateProcessorInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateMotherBoardInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateNetworkCardInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateVoiceCardInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateVoiceCardExtInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateGraphicsCardInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateBluetoothInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateKeyboardInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateMouseInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateMonitorInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateCDDriveInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateBatteryInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateFanInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateCameraInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateOutline(unsigned uStatus, QString strInfoJson);
|
||||
void updateSysInfo(unsigned uStatus, QString strInfoJson);
|
||||
void updateLshwFinished();
|
||||
|
||||
private:
|
||||
explicit DataWorker(QObject *parent = nullptr);
|
||||
void initDbusInterface(QDBusInterface **interface, QString strPath);
|
||||
void initDbusSession(QDBusInterface **interface, QString strPath);
|
||||
void genMonitorInfoDataFile(bool bUpdate = true);
|
||||
|
||||
public:
|
||||
static QMutex m_mutex;
|
||||
static DataWorker *m_instance;
|
||||
|
||||
private:
|
||||
QDBusInterface *m_dbusCpuFM = nullptr;
|
||||
QDBusInterface *m_dbusDevMonitor = nullptr;
|
||||
QDBusInterface *m_dbusHardwareInfo = nullptr;
|
||||
QDBusInterface *m_dbusSession = nullptr;
|
||||
};
|
||||
|
||||
#endif // DATAWORKER_H
|
|
@ -0,0 +1,6 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
HEADERS += \
|
||||
$$PWD/dataworker.h
|
||||
SOURCES += \
|
||||
$$PWD/dataworker.cpp
|
|
@ -0,0 +1,4 @@
|
|||
PROJECT_ROOTDIR = $$PWD
|
||||
PROJECT_COMPONENTLIBS = $$PWD/cclibs
|
||||
PROJECT_COMPONENTSOURCE = $$PWD/commonComponent
|
||||
PLUGIN_INSTALL_DIRS = $$[QT_INSTALL_LIBS]/kylin-assistant
|
|
@ -0,0 +1,20 @@
|
|||
TEMPLATE = aux
|
||||
|
||||
inst1.files += systemdaemon/
|
||||
inst1.files += sessiondaemon/
|
||||
inst1.path = /usr/lib/python3/dist-packages/kylin-assistant-daemon/
|
||||
|
||||
inst2.files += systemdaemon/conf/com.kylin.assistant.systemdaemon.conf
|
||||
inst2.path = /etc/dbus-1/system.d/
|
||||
inst3.files += systemdaemon/conf/com.kylin.assistant.systemdaemon.service
|
||||
inst3.path = /usr/share/dbus-1/system-services/
|
||||
inst4.files += systemdaemon/conf/com.kylin.assistant.systemdaemon.policy
|
||||
inst4.path = /usr/share/polkit-1/actions/
|
||||
inst5.files += sessiondaemon/conf/com.kylin.assistant.sessiondaemon.service
|
||||
inst5.path = /usr/share/dbus-1/services/
|
||||
|
||||
INSTALLS += inst1 \
|
||||
inst2 \
|
||||
inst3 \
|
||||
inst4 \
|
||||
inst5 \
|
|
@ -0,0 +1,112 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
import glob
|
||||
|
||||
AudioAdaptor_Product= "Product"
|
||||
AudioAdaptor_Manufacturer= "Vendor"
|
||||
AudioAdaptor_Model= "Model"
|
||||
AudioAdaptor_Type= "Description"
|
||||
AudioAdaptor_Version= "Version"
|
||||
AudioAdaptor_Businfo= "Bus Info"
|
||||
AudioAdaptor_Capabilities= "Capabilities"
|
||||
AudioAdaptor_IRQ= "IRQ"
|
||||
AudioAdaptor_Memory= "Memory"
|
||||
AudioAdaptor_Width= "Width"
|
||||
AudioAdaptor_Clock= "Clock"
|
||||
AudioAdaptor_SubVendor= "SubVendor"
|
||||
AudioAdaptor_SubDevice= "SubDevice"
|
||||
AudioAdaptor_Physicalid= "Physical ID"
|
||||
AudioAdaptor_Latency= "Latency"
|
||||
AudioAdaptor_ConfigStatus= "Config Status"
|
||||
AudioAdaptor_Driver= "Driver"
|
||||
AudioAdaptor_DriverMod= "Driver Modules"
|
||||
AudioAdaptor_DriverStatus= "Driver Status"
|
||||
AudioAdaptor_DriverActiveCMD= "Driver Activation Cmd"
|
||||
|
||||
|
||||
class AudioAdaptor():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getAudioAdaptorInfoExt(self):
|
||||
summary = {"list":[]}
|
||||
index = 0
|
||||
audioAdaptorList = self.cmdTool.loadSoundInfoFromPacmd(False)
|
||||
|
||||
for mapInfo in audioAdaptorList :
|
||||
if len(mapInfo) > 0 :
|
||||
summary["list"].append({})
|
||||
|
||||
##名称
|
||||
if "sound_name" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Product] = mapInfo["sound_name"]
|
||||
|
||||
##制造商
|
||||
if "sound_vendor" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = mapInfo["sound_vendor"]
|
||||
|
||||
##类型
|
||||
if "sound_description" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Type] = mapInfo["sound_description"]
|
||||
|
||||
##总线信息
|
||||
#if "sound_busaddr" in mapInfo:
|
||||
# summary["list"][index][AudioAdaptor_Businfo] = mapInfo["sound_busaddr"]
|
||||
|
||||
##驱动
|
||||
#if "sound_driver" in mapInfo :
|
||||
# summary["list"][index][AudioAdaptor_Driver] = mapInfo["sound_driver"]
|
||||
|
||||
##型号
|
||||
if "sound_model" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Model] = mapInfo["sound_model"]
|
||||
|
||||
index += 1
|
||||
|
||||
if len(summary["list"]) == 0 :
|
||||
return ""
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = AudioAdaptor(cmdTool)
|
||||
pprint(cc.getAudioAdaptorInfoExt())
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[D-BUS Service]
|
||||
Name=com.kylin.assistant.sessiondaemon
|
||||
Exec=/usr/bin/kylin-assistant-sessiondaemon.py
|
|
@ -0,0 +1,728 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
|
||||
class KACmdTool():
|
||||
|
||||
def __init__(self):
|
||||
self.lshwSystemList = []
|
||||
self.lshwDiskList = []
|
||||
self.lshwCpuList = []
|
||||
self.lshwStorageList = []
|
||||
self.lshwMemoryList = []
|
||||
self.lshwDisplayList = []
|
||||
self.lshwMultimediaList = []
|
||||
self.lshwNetworkList = []
|
||||
self.lshwUsbList = []
|
||||
self.lshwCDRomList = []
|
||||
self.lsblkSmartList = []
|
||||
self.dmesgGPUList = []
|
||||
self.nvidiaGpuList = []
|
||||
self.pacmdSoundList = []
|
||||
pass
|
||||
|
||||
def loadHwinfoUsbinfo(self, info, summary, mapInfo):
|
||||
add = True
|
||||
for item in summary:
|
||||
if "SysFS BusID" in item:
|
||||
curBus = item["SysFS BusID"]
|
||||
newBus = mapInfo["SysFS BusID"]
|
||||
curBus = re.sub("\\.[0-9]{1,2}$", "", curBus)
|
||||
newBus = re.sub("\\.[0-9]{1,2}$", "", newBus)
|
||||
if curBus == newBus :
|
||||
add = False
|
||||
break
|
||||
## 这个是用来过滤,没有接入任何设备的usb接口
|
||||
if "Model" in mapInfo and "Linux Foundation" in mapInfo["Model"] :
|
||||
add = False
|
||||
|
||||
if "Hardware Class" in mapInfo and "hub".lower() in mapInfo["Hardware Class"].lower() :
|
||||
add = False
|
||||
|
||||
## 打印机几信息不从hwinfo --usb里面获取,需要过滤
|
||||
if "Printer".lower() in info.lower() or "LaserJet".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
## 提前过滤掉键盘鼠标
|
||||
if "mouse".lower() in info.lower() or "keyboard".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
if "Wacom".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
if add :
|
||||
summary["list"].append(mapInfo)
|
||||
|
||||
def loadInfoFromHwinfo(self, param):
|
||||
summary = {"list":[]}
|
||||
|
||||
args = ["hwinfo", param]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
result = bytes.decode(l, "utf-8", "ignore")
|
||||
if result :
|
||||
allinfo += result
|
||||
|
||||
infoList = allinfo.split("\n\n")
|
||||
for info in infoList:
|
||||
if len(info) != 0 :
|
||||
mapInfo = {}
|
||||
infoLines = info.split("\n")
|
||||
for line in infoLines:
|
||||
words = line.split(": ")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
if words[0].strip() in mapInfo:
|
||||
mapInfo[words[0].strip()] += " "
|
||||
result = re.findall(".*\"(.*)\".*", words[1])
|
||||
if result and len(result) > 0 :
|
||||
key = words[0].strip()
|
||||
value = result[0]
|
||||
##这里是为了防止 "usb-storage", "sr" -》 usb-storage", "sr
|
||||
if key == "Driver" :
|
||||
value = value.replace("\"", "");
|
||||
if key in mapInfo :
|
||||
mapInfo[key] += value;
|
||||
else :
|
||||
mapInfo[key] = value;
|
||||
else :
|
||||
if words[0].strip() == "Resolution" and words[0].strip() in mapInfo :
|
||||
mapInfo[words[0].strip()] += words[1].strip();
|
||||
else :
|
||||
mapInfo[words[0].strip()] = words[1].strip();
|
||||
|
||||
if "--usb" == param :
|
||||
self.loadHwinfoUsbinfo(info, summary, mapInfo)
|
||||
elif "--keyboard" == param or "--mouse" == param :
|
||||
if "Linux Foundation" not in info and "Elite Remote Control Driver" not in info \
|
||||
and "Model: \"serial console\"" not in info and "Wacom".lower() not in info.lower() :
|
||||
summary["list"].append(mapInfo)
|
||||
else :
|
||||
summary["list"].append(mapInfo)
|
||||
return summary
|
||||
|
||||
def loadDiskInfoFromSmart(self, devName, mapInfo) :
|
||||
indexName = ""
|
||||
|
||||
args = ["smartctl", "--all", "/dev/"+devName]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infos = allinfo.split("\n")
|
||||
for line in infos:
|
||||
if len(line) > 0 :
|
||||
index = line.find(": ")
|
||||
if index > 0 and not re.findall("^[\s\S]*[\d]:[\d][\s\S]*$", line) and "Error" not in line and "hh:mm:SS" not in line :
|
||||
if line.find("(") < index and line.find(")") > index :
|
||||
continue
|
||||
if line.find("[") < index and line.find("]") > index :
|
||||
continue
|
||||
words = line.split(": ")
|
||||
if len(words) != 2 and "SATA Version is" not in words :
|
||||
continue
|
||||
indexName = words[0].strip().replace(" is", "")
|
||||
if indexName in mapInfo :
|
||||
mapInfo[indexName] += ", "
|
||||
mapInfo[indexName] += words[1].strip()
|
||||
else :
|
||||
mapInfo[indexName] = words[1].strip()
|
||||
continue
|
||||
|
||||
if len(indexName) > 0 and (line.startswith("\t\t") or line.startswith(" ")) and ":" not in line :
|
||||
if indexName in mapInfo :
|
||||
mapInfo[indexName] += ", "
|
||||
mapInfo[indexName] += line.strip()
|
||||
else :
|
||||
mapInfo[indexName] = line.strip()
|
||||
continue
|
||||
|
||||
indexName = ""
|
||||
# 1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
|
||||
result = re.findall("\s*[0-9]+\s+([\w\_]+)\s+0x[0-9a-fA-F\-]+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[\w]+\s+[\w]+\s+[\w\-]+\s+([0-9]+)$", line)
|
||||
if result and len(result) > 0:
|
||||
mapInfo[result[0][0]] = result[0][1]
|
||||
continue;
|
||||
|
||||
strList = []
|
||||
if line.endswith(")") :
|
||||
leftBracket = line.find("(")
|
||||
if leftBracket > 0 :
|
||||
key = line[:leftBracket].strip()
|
||||
strList = key.split(" ")
|
||||
if len(strList) > 2 :
|
||||
strList[-1] += line[leftBracket:]
|
||||
elif len(strList) == 0 :
|
||||
strList = line.strip().split(" ")
|
||||
|
||||
if len(strList) < 5 :
|
||||
continue
|
||||
|
||||
if "Power_On_Hours" in line :
|
||||
mapInfo["Power_On_Hours"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Power_Cycle_Count" in line :
|
||||
mapInfo["Power_Cycle_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Raw_Read_Error_Rate" in line :
|
||||
mapInfo["Raw_Read_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Spin_Up_Time" in line :
|
||||
mapInfo["Spin_Up_Time"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Start_Stop_Count" in line :
|
||||
mapInfo["Start_Stop_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Reallocated_Sector_Ct" in line :
|
||||
mapInfo["Reallocated_Sector_Ct"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Seek_Error_Rate" in line :
|
||||
mapInfo["Seek_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Spin_Retry_Count" in line :
|
||||
mapInfo["Spin_Retry_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Calibration_Retry_Count" in line :
|
||||
mapInfo["Calibration_Retry_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "G-Sense_Error_Rate" in line :
|
||||
mapInfo["G-Sense_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Power-Off_Retract_Count" in line :
|
||||
mapInfo["Power-Off_Retract_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Load_Cycle_Count" in line :
|
||||
mapInfo["Load_Cycle_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Temperature_Celsius" in line :
|
||||
mapInfo["Temperature_Celsius"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Reallocated_Event_Count" in line :
|
||||
mapInfo["Reallocated_Event_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Current_Pending_Sector" in line :
|
||||
mapInfo["Current_Pending_Sector"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Offline_Uncorrectable" in line :
|
||||
mapInfo["Offline_Uncorrectable"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "UDMA_CRC_Error_Count" in line :
|
||||
mapInfo["UDMA_CRC_Error_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Multi_Zone_Error_Rate" in line :
|
||||
mapInfo["Multi_Zone_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
return mapInfo
|
||||
|
||||
def loadDiskInfoFromLsblk(self) :
|
||||
args = ["lsblk", "-d", "-o", "name,rota,rm,maj:min"]
|
||||
pipe = subprocess.Popen(args, env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
lines = allinfo.split("\n");
|
||||
for line in lines :
|
||||
words = re.sub("[\s]+", " ", line).strip().split(" ")
|
||||
if len(words) != 4 or words[0] == "NAME" :
|
||||
continue
|
||||
mapInfo = {}
|
||||
mapInfo["dev_name"] = words[0].strip()
|
||||
mapInfo["dev_rota"] = words[1].strip()
|
||||
mapInfo["dev_removeable"] = words[2].strip()
|
||||
mapInfo["dev_majmin"] = words[3].strip()
|
||||
self.loadDiskInfoFromSmart(words[0].strip(), mapInfo)
|
||||
self.lsblkSmartList.append(mapInfo)
|
||||
pass
|
||||
|
||||
def getInfoFromLshw(self, info, mapInfo) :
|
||||
infoList = info.split("\n")
|
||||
for infoItem in infoList:
|
||||
words = infoItem.split(": ")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
if "configuration" in words[0] :
|
||||
keyValues = words[1].split(" ")
|
||||
for keyValue in keyValues :
|
||||
attr = keyValue.split("=")
|
||||
if len(attr) != 2 :
|
||||
continue
|
||||
mapInfo[attr[0].strip()] = attr[1].strip()
|
||||
elif "resources" in words[0] :
|
||||
keyValues = words[1].split(" ")
|
||||
for keyValue in keyValues:
|
||||
attr = keyValue.split(":")
|
||||
if len(attr) != 2 :
|
||||
continue
|
||||
if attr[0].strip() in mapInfo :
|
||||
mapInfo[attr[0].strip()] += " "+attr[1].strip()
|
||||
else :
|
||||
mapInfo[attr[0].strip()] = attr[1].strip()
|
||||
else :
|
||||
mapInfo[words[0].strip()] = words[1].strip()
|
||||
|
||||
|
||||
def loadInfoFromLshw(self, forceLoad = True):
|
||||
if not forceLoad and len(self.lshwSystemList) > 0 :
|
||||
return
|
||||
|
||||
args = ["lshw"]
|
||||
pipe = subprocess.Popen(args, env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
items = allinfo.split("*-");
|
||||
isFirst = True
|
||||
self.lshwSystemList = []
|
||||
self.lshwDiskList = []
|
||||
self.lshwCpuList = []
|
||||
self.lshwStorageList = []
|
||||
self.lshwMemoryList = []
|
||||
self.lshwDisplayList = []
|
||||
self.lshwMultimediaList = []
|
||||
self.lshwNetworkList = []
|
||||
self.lshwUsbList = []
|
||||
self.lshwCDRomList = []
|
||||
for item in items :
|
||||
if len(item) > 0 :
|
||||
mapInfo = {}
|
||||
if isFirst :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwSystemList.append(mapInfo)
|
||||
isFirst = False
|
||||
continue
|
||||
if item.startswith("cpu") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwCpuList.append(mapInfo)
|
||||
elif item.startswith("disk") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwDiskList.append(mapInfo)
|
||||
elif item.startswith("storage") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwStorageList.append(mapInfo)
|
||||
elif (item.startswith("memory") and not item.startswith("memory UNCLAIMED")) or item.startswith("bank") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwMemoryList.append(mapInfo)
|
||||
elif item.startswith("display") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwDisplayList.append(mapInfo)
|
||||
elif item.startswith("multimedia") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwMultimediaList.append(mapInfo)
|
||||
elif item.startswith("network") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
if not re.findall(".*network:[0-9] DISABLED.*", item) :
|
||||
self.lshwNetworkList.append(mapInfo)
|
||||
elif item.startswith("usb") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
if "description" in mapInfo and "Audio device" in mapInfo["description"] :
|
||||
self.lshwMultimediaList.append(mapInfo)
|
||||
else :
|
||||
self.lshwUsbList.append(mapInfo)
|
||||
elif item.startswith("cdrom") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwCDRomList.append(mapInfo)
|
||||
|
||||
def loadNetworkInfoFromIfconfig(self):
|
||||
args = ["ifconfig"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
items = allinfo.split("\n\n")
|
||||
for item in items :
|
||||
lines = item.strip().split("\n")
|
||||
lineCount = len(lines)
|
||||
mapInfo = {}
|
||||
for i in range(lineCount) :
|
||||
if i == 0 :
|
||||
result = re.findall("(\S+)\s+.*", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetName"] = result[0].strip().strip(":")
|
||||
result = re.findall("mtu\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMTU"] = result[0].strip()
|
||||
else :
|
||||
result = re.findall("inet\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetIp"] = result[0].strip()
|
||||
result = re.findall("netmask\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMask"] = result[0].strip()
|
||||
result = re.findall("broadcast\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetBroadcast"] = result[0].strip()
|
||||
result = re.findall("inet6\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetIp6"] = result[0].strip()
|
||||
result = re.findall("ether\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMac"] = result[0].strip()
|
||||
result = re.findall("RX packets\s+.*\((.*)\)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetRxData"] = result[0].strip()
|
||||
result = re.findall("TX packets\s+.*\((.*)\)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetTxData"] = result[0].strip()
|
||||
|
||||
if len(mapInfo) > 0 :
|
||||
infoList.append(mapInfo)
|
||||
|
||||
return infoList
|
||||
|
||||
def loadBluetoothInfo(self, mapInfo):
|
||||
if "BD Address" not in mapInfo :
|
||||
return
|
||||
pass
|
||||
|
||||
def loadInfoFromHciconfig(self):
|
||||
args = ["hciconfig", "-a"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
items = allinfo.split("\n\n")
|
||||
for item in items :
|
||||
if len(item) == 0 :
|
||||
continue
|
||||
mapInfo = {}
|
||||
isFirstLine = True
|
||||
lines = item.strip().split("\n")
|
||||
for line in lines :
|
||||
if isFirstLine :
|
||||
result = re.findall("(hci[0-9]+):", line)
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["dev_name"] = result[0]
|
||||
line = re.sub(result[0]+":","", line)
|
||||
isFirstLine = False
|
||||
linepairs = line.strip().split(" ")
|
||||
if len(linepairs) < 1 :
|
||||
continue
|
||||
for pair in linepairs :
|
||||
words = pair.strip().split(": ")
|
||||
if len(words) == 2 :
|
||||
mapInfo[words[0].strip()] = words[1].strip()
|
||||
self.loadBluetoothInfo(mapInfo)
|
||||
if len(mapInfo) > 0 :
|
||||
infoList.append(mapInfo)
|
||||
|
||||
return infoList
|
||||
|
||||
def loadGPUInfoFromDmesg(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.dmesgGPUList) > 0 :
|
||||
return None
|
||||
args = ["dmesg"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
lines = allinfo.split("\n")
|
||||
mapInfo = {}
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
result = re.findall(".*RAM width ([0-9]*bits) (.*DDR.*)", line)
|
||||
if result and len(result) > 0 :
|
||||
membitwidth = result[0][0]
|
||||
memtype = result[0][1]
|
||||
mapInfo["mem_bitwidth"] = membitwidth
|
||||
mapInfo["mem_type"] = memtype
|
||||
continue
|
||||
|
||||
result = re.findall(".*RAM=([0-9]*)M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
result = re.findall(".*RAM: ([0-9]*) M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
result = re.findall(".*RAM Size ([0-9]*)M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
if len(mapInfo) == 0 :
|
||||
mapInfo["size"] = ""
|
||||
self.dmesgGPUList.append(mapInfo)
|
||||
else :
|
||||
self.dmesgGPUList.append(mapInfo)
|
||||
return self.dmesgGPUList
|
||||
|
||||
def loadGPUInfoFromNvidiaSmi(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.nvidiaGpuList) > 0 :
|
||||
return self.nvidiaGpuList
|
||||
if not os.path.exists("/usr/bin/nvidia-smi") :
|
||||
return None
|
||||
args = ["/usr/bin/nvidia-smi", "-q", "-d", "MEMORY,CLOCK"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
value = re.findall("\nGPU (.*)", allinfo)
|
||||
for gpuBusId in value :
|
||||
singleInfos = allinfo.split("\nGPU ")
|
||||
for singleInfo in singleInfos :
|
||||
if singleInfo.startswith(gpuBusId) :
|
||||
words = gpuBusId.split(":", 1)
|
||||
gpuOne = {}
|
||||
memFree = 0
|
||||
memUsed = 0
|
||||
if len(words) == 2 :
|
||||
gpuOne["nvidia_id"] = words[1]
|
||||
gpuOne["nvidia_mem"] = ""
|
||||
lines = singleInfo.split("\n")
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
words = line.strip().split(":")
|
||||
if len(words) == 1 :
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
if words[0] == "FB Memory Usage" :
|
||||
isFBSession = True
|
||||
elif words[0] == "Clocks" :
|
||||
isClockSession = True
|
||||
elif words[0] == "Max Clocks" :
|
||||
isMaxClockSession = True
|
||||
else :
|
||||
if len(words) == 2 :
|
||||
if isFBSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Total" :
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
size = float(result[0])
|
||||
if size % 128 != 0 :
|
||||
size = size + 128 - (size%128)
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
gpuOne["nvidia_mem"] = sizeS
|
||||
else :
|
||||
gpuOne["nvidia_mem"] = valW
|
||||
elif keyW == "Used" :
|
||||
gpuOne["nvidia_mem_used"] = valW
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
memUsed = float(result[0])
|
||||
elif keyW == "Free" :
|
||||
gpuOne["nvidia_mem_free"] = valW
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
memFree = float(result[0])
|
||||
elif isClockSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Graphics" :
|
||||
if "N/A" not in valW and len(valW) > 0 :
|
||||
gpuOne["nvidia_clock"] = valW
|
||||
elif isMaxClockSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Graphics" :
|
||||
if "N/A" not in valW and len(valW) > 0 :
|
||||
gpuOne["nvidia_maxclock"] = valW
|
||||
else :
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
if len(gpuOne) > 0 :
|
||||
if memFree != 0 or memUsed != 0 :
|
||||
gpuOne["nvidia_mem_percent"] = float("%0.1f"%((memUsed/(memFree+memUsed))*100))
|
||||
infoList.append(gpuOne)
|
||||
self.nvidiaGpuList = infoList
|
||||
return infoList
|
||||
|
||||
def loadSoundInfoFromPacmd(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.pacmdSoundList) > 0 :
|
||||
return self.pacmdSoundList
|
||||
if not os.path.exists("/usr/bin/pacmd") :
|
||||
return None
|
||||
|
||||
args = ["/usr/bin/pacmd", "list-cards"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
value = re.findall("index: (.*)", allinfo)
|
||||
for cardId in value :
|
||||
singleInfos = allinfo.split("index: ")
|
||||
for singleInfo in singleInfos :
|
||||
if singleInfo.startswith(cardId) :
|
||||
soundCardOne = {}
|
||||
lines = singleInfo.split("\n")
|
||||
isPropSession = False
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
if not isPropSession :
|
||||
words = line.strip().split(":")
|
||||
if words[0] == "properties" :
|
||||
isPropSession = True
|
||||
else :
|
||||
if isPropSession :
|
||||
propWords = line.strip().split("=")
|
||||
if len(propWords) == 2 :
|
||||
keyPropW = propWords[0].strip()
|
||||
valPropW = propWords[1].strip().replace("\"", "")
|
||||
if keyPropW == "alsa.card_name" : #名称
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_name"] = valPropW
|
||||
elif keyPropW == "alsa.long_card_name" : #型号
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_model"] = valPropW
|
||||
elif keyPropW == "device.vendor.name" : #厂商
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_vendor"] = valPropW
|
||||
elif keyPropW == "alsa.driver_name" : #驱动
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_driver"] = valPropW
|
||||
elif keyPropW == "device.icon_name" : #?
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_icon"] = valPropW
|
||||
elif keyPropW == "device.bus_path" : #总线地址
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_busaddr"] = valPropW
|
||||
elif keyPropW == "device.description" : #描述
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_description"] = valPropW
|
||||
if "sound_icon" in soundCardOne and "sound_driver" not in soundCardOne :
|
||||
soundCardOne["sound_driver"] = soundCardOne["sound_icon"]
|
||||
if len(soundCardOne) > 0 :
|
||||
infoList.append(soundCardOne)
|
||||
self.pacmdSoundList = infoList
|
||||
return infoList
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KACmdTool()
|
||||
cc.loadInfoFromLshw()
|
||||
# pprint(cc.lshwSystemList)
|
||||
# pprint(cc.lshwCpuList)
|
||||
# pprint(cc.lshwStorageList)
|
||||
# pprint(cc.lshwMemoryList)
|
||||
# pprint(cc.lshwDisplayList)
|
||||
# pprint(cc.lshwMultimediaList)
|
||||
# pprint(cc.lshwNetworkList)
|
||||
# pprint(cc.lshwUsbList)
|
||||
# pprint(cc.lshwCDRomList)
|
||||
# pprint(cc.loadNetworkInfoFromIfconfig())
|
||||
# pprint(cc.loadInfoFromHciconfig())
|
||||
# pprint(cc.loadGPUInfoFromNvidiaSmi())
|
||||
pprint(cc.loadSoundInfoFromPacmd())
|
||||
|
||||
# diskList = cc.loadInfoFromHwinfo("--disk")
|
||||
# cc.loadDiskInfoFromLsblk()
|
||||
# if "list" in diskList and len(diskList["list"]) > 0 :
|
||||
# length = len(diskList["list"])
|
||||
# for i in range(length) :
|
||||
# if "SysFS BusID" in diskList["list"][i] :
|
||||
# for mapInfo in cc.lshwDiskList :
|
||||
# if "bus info" in mapInfo :
|
||||
# words = mapInfo["bus info"].split("@")
|
||||
# if len(words) != 2 :
|
||||
# continue
|
||||
# key = words[1].strip()
|
||||
# key = key.replace(".",":")
|
||||
# if key != diskList["list"][i]["SysFS BusID"] :
|
||||
# continue
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# if "SysFS Device Link" in diskList["list"][i]:
|
||||
# for mapInfo in cc.lshwStorageList :
|
||||
# if "bus info" in mapInfo :
|
||||
# words = mapInfo["bus info"].split("@")
|
||||
# if len(words) != 2 :
|
||||
# continue
|
||||
# key = words[1].strip().lower()
|
||||
# if key not in diskList["list"][i]["SysFS Device Link"].lower() :
|
||||
# continue
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# for mapInfo in cc.lsblkSmartList :
|
||||
# if "dev_name" in mapInfo and "Device File" in diskList["list"][i] \
|
||||
# and mapInfo["dev_name"] in diskList["list"][i]["Device File"] :
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# pprint(diskList)
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from subprocess import PIPE
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
from gi.repository import GLib
|
||||
|
||||
import subprocess
|
||||
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
from audioadaptorthread import AudioAdaptor
|
||||
from kacmdtool import KACmdTool
|
||||
|
||||
OBJPATH = '/com/kylin/assistant/sessiondaemon'
|
||||
INTERFACE = 'com.kylin.assistant.sessiondaemon'
|
||||
|
||||
THREAD_INDEX_OUTLINE = 0
|
||||
THREAD_INDEX_HARDWARE = 1
|
||||
THREAD_INDEX_MEMORY = 2
|
||||
THREAD_INDEX_NETWORK = 3
|
||||
THREAD_INDEX_AUDIOADAPTER = 4
|
||||
THREAD_INDEX_SYSTEMBOARD = 5
|
||||
THREAD_INDEX_RELOADLSHW = 6
|
||||
THREAD_INDEX_MAX = 7
|
||||
|
||||
class HardwareInfo(dbus.service.Object):
|
||||
def __init__(self, system_bus, mainloop):
|
||||
# Init dbus service.
|
||||
dbus.service.Object.__init__(self, system_bus, OBJPATH)
|
||||
self.mainloop = mainloop
|
||||
self.cmdtool = KACmdTool()
|
||||
|
||||
self.threadPool = [None] * THREAD_INDEX_MAX
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='', sender_keyword='sender')
|
||||
def exit(self, sender = None):
|
||||
self.mainloop.quit()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def getSoundCardsExt(self, sender=None):
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER] = KAThread(AudioAdaptor(self.cmdtool).getAudioAdaptorInfoExt, None, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER].start()
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER].join()
|
||||
return self.threadPool[THREAD_INDEX_AUDIOADAPTER].getResult()
|
||||
|
||||
if __name__ == '__main__':
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
mainloop = GLib.MainLoop()
|
||||
# Init dbus.
|
||||
system_bus = dbus.SessionBus()
|
||||
bus_name = dbus.service.BusName("com.kylin.assistant.sessiondaemon", system_bus)
|
||||
HardwareInfo(system_bus, mainloop)
|
||||
mainloop.run()
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
from kacmdtool import KACmdTool
|
||||
|
||||
###Machine Outline
|
||||
MI_MANUFACTURER = "Manufacturer" #整机制造商
|
||||
MI_MACHINEMODEL = "MachineModel" #整机型号
|
||||
MI_SERIALNUM = "SerialNum" #SN
|
||||
MI_VERSION = "Version" #整机版本
|
||||
MI_SYSTEMBITS = "SystemBits" #系统位数
|
||||
MI_KERNELARCH = "KernelArch" #内核架构
|
||||
MI_KERNELVERSION = "KernelVersion" #内核版本
|
||||
MI_HOSTNAME = "HostName" #主机名
|
||||
MI_OSVERSION = "OSVersion" #操作系统版本
|
||||
MI_OSTYPES = "OS Types" #操作系统类型
|
||||
MI_RUNINGTIME = "Running Time" #系统持续运行时间
|
||||
MI_PROCESSOR = "Processor" #处理器
|
||||
MI_MEMORY = "Memory" #内存
|
||||
MI_MAINBOARD = "MainBoard" #主板
|
||||
MI_HARDDISK = "HardDisk" #硬盘
|
||||
MI_GRAPHICSCARD = "GraphicsCard" #显卡
|
||||
MI_MONITOR = "Monitor" #显示器
|
||||
MI_NETWORKCARD = "NetworkCard" #网卡
|
||||
MI_SOUNDCARD = "SoundCard" #声卡
|
||||
|
||||
##PROCESSOR
|
||||
Pro_Manufacturer= "manufacturer"
|
||||
Pro_Product= "processor"
|
||||
Pro_Architecture= "architecture"
|
||||
Pro_Frequency= "fref"
|
||||
Pro_Frequency_Max= "fref_max"
|
||||
Pro_Threads= "threads_num"
|
||||
Pro_Family= "Family"
|
||||
Pro_Model= "Model"
|
||||
Pro_Stepping= "Stepping"
|
||||
Pro_L1dCache= "L1d_cache"
|
||||
Pro_L1iCache= "L1i_cache"
|
||||
Pro_L2Cache= "L2_cache"
|
||||
Pro_L3Cache= "L3_cache"
|
||||
Pro_Cores= "cores_num"
|
||||
Pro_Cores_Online= "cores_num_online"
|
||||
Pro_Ext_Instruction_Set="ext_instruction_set"
|
||||
PSI_ROOT = "processor" #处理器根
|
||||
|
||||
##MEMORY
|
||||
Mem_Manufacturer= "Manufacturer"
|
||||
Mem_BankLocator= "Bank Locator"
|
||||
Mem_Type= "Type"
|
||||
Mem_TypeDetail= "Type Detail"
|
||||
Mem_TotalWidth= "Total Width"
|
||||
Mem_DataWidth= "Data Width"
|
||||
Mem_SerialNumber= "Serial Number"
|
||||
Mem_MinVoltage= "Minimum Voltage"
|
||||
Mem_MaxVoltage= "Maximum Voltage"
|
||||
Mem_ConfVoltage= "Configured Voltage"
|
||||
Mem_Rank= "Rank"
|
||||
Mem_FormFactor= "Form Factor"
|
||||
Mem_Product= "Product"
|
||||
|
||||
MMI_ROOT = "memory" #内存
|
||||
MMI_SLOT = "slot" #插槽
|
||||
MMI_NAME = "name" #名称
|
||||
MMI_FREQ = "freq" #当前频率
|
||||
MMI_BUSWIDTH = "bus_width" #总线位宽
|
||||
MMI_DATAWIDTH = "data_width" #数据位宽
|
||||
MMI_TYPE = "type" #类型
|
||||
MMI_TOTALCAPACITY = "total_capacity" #总容量
|
||||
MMI_USEDCAPACITY = "used_capacity" #已用容量
|
||||
MMI_SERIALNUM = "serail_num" #序列号
|
||||
MMI_MANUFACTURER = "manufacturer" #制造商
|
||||
MMI_MODEL = "model" #型号
|
||||
MMI_SPEED = "speed" #速率
|
||||
MMI_CONFIGSPEED = "config_speed" #配置速率
|
||||
MMI_PIPE = "pipe" #通道
|
||||
MMI_ARRAYHANDLE = "array_handle" #数组程序
|
||||
MMI_PARTNUMBER = "partnum" #部件号码
|
||||
MMI_PHYSICALID = "physicalid" #物理ID
|
||||
|
||||
###HARD DISK
|
||||
HDI_ROOT = "harddisk" #硬盘
|
||||
HDI_MANUFACTURER = "manufacturer" #硬盘品牌
|
||||
HDI_NAME = "name" #名称
|
||||
HDI_CAPACITY = "capacity" #容量
|
||||
HDI_USEDTIMES = "used_times" #已使用次数
|
||||
HDI_INTERFACE = "interface" #接口
|
||||
HDI_ISMAINDISK = "is_maindisk" #主硬盘(是否)
|
||||
HDI_ISSSD = "is_ssd" #硬盘类型(固态/机械)
|
||||
HDI_SERIALNUM = "serial_num" #序列号
|
||||
HDI_MODEL = "model" #型号
|
||||
HDI_TRANSRATE = "trans_rate" #数据传输率
|
||||
HDI_READSPEED = "read_speed" #磁盘读取速度
|
||||
HDI_WRITESPEED = "write_speed" #磁盘写入速度
|
||||
HDI_FIRMWAREVER = "firmware_ver" #固件版本
|
||||
HDI_ROTA = "rota" #机械转速
|
||||
|
||||
###DEV MONITOR
|
||||
DEVMONITOR_ROOT = "device_monitor" #设备监测
|
||||
DEVMONITOR_DEVTEMP = "device_temp" #设备温度
|
||||
DEVMONITOR_DEVTEMPS = "device_temps" #设备温度列表
|
||||
DEVMONITOR_DEVTEMP_HIGH = "device_temp_high" #设备高温
|
||||
DEVMONITOR_DEVTEMP_CRIT = "device_temp_crit" #设备异常温
|
||||
DEVMONITOR_DEVTEMP_NAME = "device_name" #设备名称
|
||||
DEVMONITOR_DEVTEMP_VALUE = "device_temp_value" #设备温度值
|
||||
DEVMONITOR_DEVUSAGE = "device_usage" #设备使用率
|
||||
DEVMONITOR_DEVUSAGE_NAME = "device_name" #设备名称
|
||||
DEVMONITOR_DEVUSAGE_USED = "device_usage_used" #设备使用率
|
||||
DEVMONITOR_DEVUSAGE_TOTAL = "device_usage_total" #使用总值
|
||||
|
||||
###CPU FM
|
||||
Cpufm_Root = "cpu_fm" # cpu调频
|
||||
Cpufm_Average_Corefreq = "cpu_corefreq" #当前cpu核心平均主频
|
||||
Cpufm_Models = "cpu_model_list" #cpu调频模式列表
|
||||
Cpufm_Current_Model = "cpu_curmodel" #cpu当前模式
|
||||
Cpufm_Model_Performance = "performance" #性能模式
|
||||
Cpufm_Model_Powersave = "powersave" #省电模式
|
||||
Cpufm_Model_Userspace = "userspace" #自定义
|
||||
Cpufm_Model_Schedutil = "schedutil" #均衡模式
|
||||
Cpufm_Freqs = "cpu_freq_list" #cpu频率列表
|
||||
Cpufm_CurFreq = "cur_freq" #cpu调频
|
||||
|
||||
###NETWORK CARD
|
||||
NWI_ROOT = "network_card" #网卡
|
||||
|
||||
###VOICE CARD
|
||||
VCI_ROOT = "voice_card" #声卡
|
||||
|
||||
###MOTHER BOARD
|
||||
MBI_ROOT= "mother_board" #主板
|
||||
MBI_NAME= "name" #主板名称
|
||||
MBI_CHIPSET= "chipset" #芯片组
|
||||
MBI_SERIALNUM= "serial_num" #序列号
|
||||
MBI_PUBDATE= "publish_date" #发布日期
|
||||
MBI_VERSION= "version" #主板版本
|
||||
MBI_MANUFACTURER= "manufacturer" #主板制造商
|
||||
MBI_BIOSMANUFACTURER= "bios_manufacturer" #BIOS制造商
|
||||
MBI_BIOSVERSION= "bios_version" #BIOS版本
|
||||
|
||||
###GRAPHICS CARD
|
||||
GSI_ROOT= "graphics_card" #显卡
|
||||
GSI_MANUFACTURER= "manufacturer" #厂商
|
||||
GSI_SUBSYSTEM= "subsystem" #子制造商
|
||||
GSI_NAME= "name" #名称
|
||||
GSI_ISDISCRETE= "is_discrete" #是否为独显
|
||||
GSI_CAPCITY= "capcity" #显存
|
||||
GSI_MEMTYPE= "mem_type" #显存类型
|
||||
GSI_MODEL= "model" #型号
|
||||
GSI_VERSION= "version" #版本
|
||||
GSI_BITWIDTH= "bit_width" #位宽
|
||||
GSI_IRQ= "irq" #中断
|
||||
GSI_FUNCTION= "function" #功能
|
||||
GSI_CLOCK= "clock" #时钟频率
|
||||
GSI_DESC= "description" #描述
|
||||
GSI_DRIVER= "driver" #驱动
|
||||
GSI_DBUSINFO= "dbusinfo" #总线信息
|
||||
GSI_IOPORT= "io_port" #I/O端口
|
||||
GSI_MEMORY= "memory" #内存
|
||||
GSI_PHYSICS= "physics_id" #物理ID
|
||||
GSI_DELAY= "delay" #延迟
|
||||
GSI_DEVICE= "device" #设备
|
||||
GSI_CONFSTATUS= "config_status" #配置状态
|
||||
GSI_DRIVERMODULE= "driver_module" #驱动模块
|
||||
GSI_GDDRCAPACITY= "gddr_capacity" #GDDR容量
|
||||
GSI_EGLVERSION= "egl_version" #EGL版本
|
||||
GSI_EGLAPIS= "egl_apis" #EGL接口
|
||||
GSI_GLVERSION= "gl_version" #GL版本
|
||||
GSI_GLSLVERSION= "glsl_version" #GLSL版本
|
||||
|
||||
###MONITOR
|
||||
MNI_ROOT= "monitor" #显示器
|
||||
MNI_MANUFACTURER= "manufacturer" #显示器厂商
|
||||
MNI_NAME= "name" #名称
|
||||
MNI_SIZE= "size" #屏幕尺寸
|
||||
MNI_RATIO= "ratio" #图像高宽比
|
||||
MNI_RESOLUTION= "resolution" #分辨率
|
||||
MNI_MAXAVARES= "max_resolution" #最大分辨率
|
||||
MNI_ISMAIN= "is_main" #主显示器(是/否)
|
||||
MNI_GAMMA= "gamma" #伽马值
|
||||
MNI_INTERFACE= "interface" #当前接口
|
||||
MNI_MODEL= "model" #型号
|
||||
MNI_VISIBLEAREA= "visible_area" #可视面积
|
||||
MNI_YEAR= "year" #生产年
|
||||
MNI_WEEK= "week" #生产周
|
||||
MNI_SERIALNUM= "serailnum" #序列号
|
||||
|
||||
###KEYBOARD
|
||||
KBI_ROOT= "key_board" #键盘
|
||||
KBI_DEVTYPE= "dev_type" #设备类型
|
||||
KBI_NAME= "name" #设备名称
|
||||
KBI_DEVMODEL= "dev_model" #设备型号
|
||||
KBI_MANUFACTURER= "manufacturer" #制造商
|
||||
KBI_INTERFACE= "interface" #接口
|
||||
KBI_DRIVER= "driver" #驱动
|
||||
|
||||
###MOUSE
|
||||
MSI_ROOT= "mouse" #鼠标
|
||||
MSI_DEVTYPE= "dev_type" #设备类型
|
||||
MSI_NAME= "name" #设备名称
|
||||
MSI_DEVMODEL= "dev_model" #设备型号
|
||||
MSI_MANUFACTURER= "manufacturer" #制造商
|
||||
MSI_INTERFACE= "interface" #接口
|
||||
MSI_DRIVER= "driver" #驱动
|
||||
|
||||
###BATTERY
|
||||
BTI_ROOT= "battery" #电池
|
||||
BTI_SERAILNUM= "serailnum" #序列号
|
||||
BTI_MODEL= "model" #型号
|
||||
BTI_MANUFACTURER= "manufacturer" #制造商
|
||||
BTI_TTE= "time_to_empty" #预计使用时间
|
||||
BTI_USEDTIMES= "used_times" #使用次数
|
||||
BTI_ENERGYFULL= "energy_full" #满电容量
|
||||
BTI_ENERGY= "energy" #当前容量
|
||||
BTI_STATE= "state" #状态
|
||||
BTI_PERCENTAGE= "percentage" #电量
|
||||
|
||||
###CDDRIVE
|
||||
CDI_ROOT= "cddrive" #光驱
|
||||
CDI_NAME= "name" #名称
|
||||
CDI_MANUFACTURER= "manufacturer" #制造商
|
||||
CDI_VERSION= "version" #版本
|
||||
CDI_MODEL= "model" #型号
|
||||
CDI_BUSINFO= "businfo" #总线信息
|
||||
CDI_DRIVER= "driver" #驱动
|
||||
CDI_SPEED= "speed" #速度
|
||||
CDI_SERAILNUM= "serailnum" #序列号
|
||||
CDI_DEVICENUM= "devicenum" #设备编号
|
||||
|
||||
CAI_ROOT= "camera" #摄像头
|
||||
CAI_NAME= "name" #设备名称
|
||||
CAI_RESOLUTION= "resolution" #分辨率
|
||||
CAI_MANUFACTURER= "manufacturer" #制造商
|
||||
CAI_MODEL= "model" #型号
|
||||
CAI_INTERFACE= "interface" #接口
|
||||
CAI_DRIVER= "driver" #驱动
|
||||
CAI_TYPE= "type" #类型
|
||||
CAI_VERSION= "version" #版本
|
||||
CAI_BUSINFO= "businfo" #总线信息
|
||||
CAI_SPEED= "speed" #速度
|
||||
|
||||
###BLUETOOTH
|
||||
BLI_ROOT= "bluetooth" #蓝牙
|
||||
BLI_BUSADDR= "bus_addr" #总线地址
|
||||
BLI_FUNCTION= "function" #功能
|
||||
BLI_FREQ= "freq" #频率
|
||||
BLI_CONF= "configuration" #配置
|
||||
BLI_DEVTYPE= "dev_type" #设备类型
|
||||
BLI_ID= "id" #ID号
|
||||
BLI_DEVMODEL= "dev_model" #设备型号
|
||||
BLI_RESOURCE= "resource" #资源
|
||||
BLI_MANUFACTURER= "manufacturer" #制造商
|
||||
BLI_DEVVERSION= "dev_version" #设备版本
|
||||
BLI_DATAWIDTH= "data_width" #数据宽度
|
||||
BLI_NAME= "name" #名称
|
||||
BLI_DRIVER= "driver" #驱动
|
||||
BLI_SPEED= "speed" #速度
|
||||
BLI_SERIALNUM= "serial_num" #序列号
|
||||
BLI_ADDRESS= "address" #蓝牙地址
|
||||
BLI_LINKMODE= "link_mode" #连接模式
|
||||
BLI_LINKPOLICY= "link_policy" #连接策略
|
||||
BLI_PRODUCT= "product" #产品
|
||||
BLI_CAPABILITIES= "capabilities" #功能
|
||||
BLI_BUS= "bus" #总线
|
||||
BLI_SCOMTU= "scomtu" #SCO MTU
|
||||
BLI_ALCMTU= "alcmtu" #ALC MTU
|
||||
BLI_PACKETTYPE= "packettype" #数据包类型
|
||||
BLI_FEATURES= "features" #特征
|
||||
|
||||
###FAN
|
||||
FAI_ROOT= "fan" #风扇
|
||||
FAI_NAME= "name" #名称
|
||||
FAI_SPEED= "speed" #转速
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
import os
|
||||
import dbus
|
||||
import signal
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
|
||||
from kahwinfo import *
|
||||
|
||||
DBUSNAME = "com.kylin.assistant.sessiondaemon"
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.environ["TERM"] = "xterm"
|
||||
os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
|
||||
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
|
||||
mainloop = GLib.MainLoop()
|
||||
|
||||
bus = dbus.SessionBus()
|
||||
name = dbus.service.BusName(DBUSNAME, bus)
|
||||
signal.signal(signal.SIGINT, lambda : mainloop.quit())
|
||||
##obj = TestObject(bus, mainloop)
|
||||
obj = HardwareInfo(bus, mainloop)
|
||||
|
||||
print("Running kyas_session_service...\n")
|
||||
mainloop.run()
|
||||
print("Ending kyas_session_service...\n")
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class KAThread(Thread):
|
||||
|
||||
def __init__(self, func, cbfunc, args):
|
||||
'''
|
||||
:param func: 可调用的对象
|
||||
:param args: 可调用对象的参数
|
||||
'''
|
||||
Thread.__init__(self)
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.cbfunc = cbfunc
|
||||
self.result = ""
|
||||
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
if self.cbfunc :
|
||||
self.cbfunc(1, self.result)
|
||||
|
||||
def getResult(self):
|
||||
return self.result
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
|
||||
import os
|
||||
import re
|
||||
import binascii
|
||||
|
||||
KILOBYTE_FACTOR = 1000.0
|
||||
MEGABYTE_FACTOR = (1000.0 * 1000.0)
|
||||
GIGABYTE_FACTOR = (1000.0 * 1000.0 * 1000.0)
|
||||
TERABYTE_FACTOR = (1000.0 * 1000.0 * 1000.0 * 1000.0)
|
||||
|
||||
def Judgment_HW990():
|
||||
if os.path.exists("/proc/hardware"):
|
||||
with open("/proc/hardware",'r') as fd:
|
||||
info = fd.readline()
|
||||
if info.find("HUAWEI Kirin 990") >= 0 or info.find("kirin990") >= 0 or info.find("HUAWEI Kirin 9006C") >= 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def Judgment_HW9A0():
|
||||
if os.path.exists("/proc/hardware"):
|
||||
with open("/proc/hardware",'r') as fd:
|
||||
info = fd.readline()
|
||||
if info.find("HUAWEI Kirin 9006C") >= 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def myctoascii(buf):
|
||||
ch = bytes(buf.encode('utf-8'))
|
||||
asci = binascii.b2a_hex(ch)
|
||||
asci = int(asci,16)
|
||||
return asci
|
||||
|
||||
def mystrip(s):
|
||||
if(len(s) == 0):
|
||||
return s
|
||||
while len(s) > 0 and myctoascii(s[0]) <= 32:
|
||||
s = s[1: ]
|
||||
k = len(s)
|
||||
while len(s) > 0 and myctoascii(s[k-1]) <= 32:
|
||||
s = s[ :k-1]
|
||||
k = len(s)
|
||||
i = 0
|
||||
while i < len(s):
|
||||
if myctoascii(s[i]) < 32:
|
||||
s = s[ :i] + s[i+1: ]
|
||||
i -= 1
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def get_url(v,p):
|
||||
vendors = {
|
||||
#CPU产商
|
||||
"INTEL":["Intel"],
|
||||
"AMD":["AMD"],
|
||||
"VIMICRO":["Vimicro"],
|
||||
#显卡产商
|
||||
"ATI":["ATI"],
|
||||
"1002":["ATI"],
|
||||
"SIS":["SIS"],
|
||||
"1039":["SIS"],
|
||||
"NVIDIA":["Nvidia"],
|
||||
"VIA":["VIA"],
|
||||
"XFX":["XFX"],
|
||||
"SUPERGRAPHIC":["Supergraphic"],
|
||||
"JINGJIA":["JJM"],
|
||||
"Wuhan Digital Engineering":["WDE"],
|
||||
#显示器产商
|
||||
"AUO":["AUO"],
|
||||
"AOC":["AOC"],
|
||||
"PHILIPS":["Philips"],
|
||||
"PHL":["Philips"],
|
||||
"LEN":["Lenovo"],
|
||||
"SEC":["SAMSUNG"],
|
||||
#电脑品牌
|
||||
"HASEE":["Hasee"],
|
||||
"FOUNDER":["Founder"],
|
||||
"TONGFANG":["Tongfang"],
|
||||
"TSINGHUA":["Tongfang"],
|
||||
"ACER":["Acer"],
|
||||
"LENOVO":["Lenovo"],
|
||||
"ASUSTEK":["ASUS"],
|
||||
"NEC":["NEC"],
|
||||
"HP":["HP"],
|
||||
"HEWLETT-PACKARD":["HP"],
|
||||
"SAMSUNG":["SAMSUNG"],
|
||||
"TOSHIBA":["TOSHIBA"],
|
||||
"APPLE":["Apple"],
|
||||
"DELL":["DELL"],
|
||||
"FUJITSU":["FUJITSU"],
|
||||
"PANASONIC":["Panasonic"],
|
||||
"SONY":["SONY"],
|
||||
"IBM":["IBM"],
|
||||
#虚拟机
|
||||
"INNOTEK":["VirtualBox"],
|
||||
"VBOX":["VirtualBox"],
|
||||
"VIRTUALBOX":["VirtualBox"],
|
||||
#网卡产商
|
||||
"3COM":["3COM"],
|
||||
"D-LINK":["D-LINK"],
|
||||
"RALINK":["Ralink"],
|
||||
"ATHEROS":["Atheros"],
|
||||
"MARVELL":["Marvell"],
|
||||
"BROADCOM":["Broadcom"],
|
||||
#硬盘产商
|
||||
"EXCELSTOR":["Excelstor"],
|
||||
"HITACHI":["Hitachi"],
|
||||
"MAXTOR":["Maxtor"],
|
||||
"WESTERN":["Western Digital"],
|
||||
"LITEON":["Liteon"],
|
||||
"SEAGATE":["Seagate"],
|
||||
"QUANTUM":["Quantum"],
|
||||
#光驱产商
|
||||
"PLDS":["PLDS"],
|
||||
"PBDS":["PLDS"],
|
||||
"HL-DT-ST":["LG"],
|
||||
"OPTIARC":["SONY"],
|
||||
"TSSTCORP":["TSSTcorp"],
|
||||
"PIONEER":["Pioneer"],
|
||||
"MATSHITA":["Panasonic"],
|
||||
#声卡产商
|
||||
"REALTEK":["Realtek"],
|
||||
"CREATIVE":["Creative"],
|
||||
"LOONGSON":["Loongson"],
|
||||
"HISILICON":["HiSilicon"],
|
||||
#摄像头
|
||||
"SONIX":["Sonix"],
|
||||
"ETRON":["Etron"],
|
||||
"AVEO":["Aveo"],
|
||||
"SYNTEK":["Syntek"],
|
||||
"EMPIA":["Empia"],
|
||||
"CHICONY":["Chicony"],
|
||||
"OMNIVISION":["OmniVision"],
|
||||
#鼠标产商
|
||||
"LOGITECH":["Logitech"],
|
||||
"SUNPLUS":["Sunplus"],
|
||||
"PRIMAX":["Primax"],
|
||||
"PIXART":["Pixart"],
|
||||
"TRUST":["Trust"],
|
||||
"1BCF":["Rapoo"],
|
||||
"AVAGO":["Avago"],
|
||||
"MICROSOFT":["Microsoft"],
|
||||
#键盘产商
|
||||
"RAPOO":["Rapoo"],
|
||||
#主板产商
|
||||
"GIGABYTE":["Gigabyte"],
|
||||
"BIOSTAR":["Biostar"],
|
||||
"COLORFUL":["Colorful"],
|
||||
"YESTON":["Yeston"],
|
||||
#指纹识别
|
||||
"UPEK":["Authentec"],
|
||||
"AUTHENTEC":["Authentec"],
|
||||
#闪存产商
|
||||
"KINGSTON":["Kingston"],
|
||||
"KINGMAX":["Kingmax"],
|
||||
"KINGBOX":["Kingbox"],
|
||||
"HYNIX":["Hynix"],
|
||||
"HYUNDAI":["Hynix"],
|
||||
"MICRON":["Micron"],
|
||||
"06C1":["Asint"],
|
||||
"ADATA":["ADATA"],
|
||||
"ZTE":["ZTE"],
|
||||
"EAGET":["Eaget"],
|
||||
"TEXAS":["Texas Instruments"],
|
||||
"MOTOROLA":["Motorola"],
|
||||
#电源产商
|
||||
"SMP":["SMP"],
|
||||
"SIMPLO":["SMP"],
|
||||
#BIOS产商
|
||||
"AMERICAN":["AMI"],
|
||||
"AWARD":["Phoenix"],
|
||||
"PHOENIX":["Phoenix"]
|
||||
}
|
||||
tmp = v.split(" ")[0]
|
||||
tmp = re.findall("([a-zA-Z0-9-]+)", tmp)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else :
|
||||
k = p.split(" ")[0]
|
||||
url = vendors.get(k.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else:
|
||||
tmp = p.split(" ")[0]
|
||||
url = vendors.get(tmp.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("JingJia", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Loongson", p, flags=re.IGNORECASE)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("Wuhan Digital Engineering", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("ATI", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("ATI", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
return v
|
|
@ -0,0 +1,309 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
import glob
|
||||
|
||||
AudioAdaptor_Product= "Product"
|
||||
AudioAdaptor_Manufacturer= "Vendor"
|
||||
AudioAdaptor_Model= "Model"
|
||||
AudioAdaptor_Type= "Description"
|
||||
AudioAdaptor_Version= "Version"
|
||||
AudioAdaptor_Businfo= "Bus Info"
|
||||
AudioAdaptor_Capabilities= "Capabilities"
|
||||
AudioAdaptor_IRQ= "IRQ"
|
||||
AudioAdaptor_Memory= "Memory"
|
||||
AudioAdaptor_Width= "Width"
|
||||
AudioAdaptor_Clock= "Clock"
|
||||
AudioAdaptor_SubVendor= "SubVendor"
|
||||
AudioAdaptor_SubDevice= "SubDevice"
|
||||
AudioAdaptor_Physicalid= "Physical ID"
|
||||
AudioAdaptor_Latency= "Latency"
|
||||
AudioAdaptor_ConfigStatus= "Config Status"
|
||||
AudioAdaptor_Driver= "Driver"
|
||||
AudioAdaptor_DriverMod= "Driver Modules"
|
||||
AudioAdaptor_DriverStatus= "Driver Status"
|
||||
AudioAdaptor_DriverActiveCMD= "Driver Activation Cmd"
|
||||
|
||||
|
||||
class AudioAdaptor():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getAudioAdaptorInfo(self):
|
||||
summary = {"list":[]}
|
||||
index = 0
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
audioAdaptorList = self.cmdTool.lshwMultimediaList
|
||||
adaptorList = self.cmdTool.loadInfoFromHwinfo("--sound")["list"]
|
||||
length = len(audioAdaptorList)
|
||||
for i in range(length) :
|
||||
if "bus info" in audioAdaptorList[i] :
|
||||
words = audioAdaptorList[i]["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip()
|
||||
isDone = False
|
||||
#key = key.replace(".",":")
|
||||
for mapInfo in adaptorList :
|
||||
if "SysFS BusID" in mapInfo :
|
||||
if key != mapInfo["SysFS BusID"] :
|
||||
continue
|
||||
audioAdaptorList[i].update(mapInfo)
|
||||
isDone = True
|
||||
if not isDone and ":" in key :
|
||||
key = key.replace(":", "-")
|
||||
for mapInfo in adaptorList :
|
||||
if "SysFS BusID" in mapInfo :
|
||||
sysBusIds = mapInfo["SysFS BusID"].split(":")
|
||||
if key not in sysBusIds :
|
||||
continue
|
||||
audioAdaptorList[i].update(mapInfo)
|
||||
isDone = True
|
||||
|
||||
|
||||
for mapInfo in audioAdaptorList :
|
||||
if len(mapInfo) > 0 :
|
||||
summary["list"].append({})
|
||||
pciAddr = ""
|
||||
##名称
|
||||
if "product" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Product] = mapInfo["product"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
devVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(devVendor) > 1 :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = devVendor[1]
|
||||
else :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
devVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(devVendor) > 1 :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = devVendor[1]
|
||||
else :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = mapInfo["SubVendor"]
|
||||
if "vendor" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Manufacturer] = mapInfo["vendor"]
|
||||
|
||||
##类型
|
||||
if "description" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Type] = mapInfo["description"]
|
||||
|
||||
##版本
|
||||
if "version" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Version] = mapInfo["version"]
|
||||
|
||||
##总线信息
|
||||
if "bus info" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Businfo] = mapInfo["bus info"]
|
||||
pciResult = re.findall("pci@(\S+)", mapInfo["bus info"])
|
||||
if pciResult :
|
||||
pciAddr = pciResult[0]
|
||||
|
||||
##功能
|
||||
if "capabilities" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Capabilities] = mapInfo["capabilities"]
|
||||
|
||||
##位宽
|
||||
if "width" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Width] = mapInfo["width"]
|
||||
|
||||
##物理ID
|
||||
if "physical id" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Physicalid] = mapInfo["physical id"]
|
||||
|
||||
##时钟频率
|
||||
if "clock" in mapInfo:
|
||||
summary["list"][index][AudioAdaptor_Clock] = mapInfo["clock"]
|
||||
|
||||
##中断
|
||||
if "irq" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_IRQ] = mapInfo["irq"]
|
||||
|
||||
##内存
|
||||
if "memory" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Memory] = mapInfo["memory"]
|
||||
|
||||
##驱动
|
||||
if "driver" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Driver] = mapInfo["driver"]
|
||||
|
||||
##延迟
|
||||
if "latency" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Latency] = mapInfo["latency"]
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Model] = mapInfo["Model"].strip("\"")
|
||||
|
||||
##子制造商
|
||||
if "SubVendor" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_SubVendor] = mapInfo["SubVendor"]
|
||||
|
||||
##子设备
|
||||
if "SubDevice" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_SubDevice] = mapInfo["SubDevice"]
|
||||
|
||||
##配置状态
|
||||
if "Config Status" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_ConfigStatus] = mapInfo["Config Status"]
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_Driver] = mapInfo["Driver"].strip("\"")
|
||||
|
||||
##驱动模块
|
||||
if "Driver Modules" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_DriverMod] = mapInfo["Driver Modules"]
|
||||
|
||||
##驱动状态
|
||||
if "Driver Status" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_DriverStatus] = mapInfo["Driver Status"]
|
||||
|
||||
##驱动激活命令
|
||||
if "Driver Activation Cmd" in mapInfo :
|
||||
summary["list"][index][AudioAdaptor_DriverActiveCMD] = mapInfo["Driver Activation Cmd"]
|
||||
|
||||
#子制造商
|
||||
if len(pciAddr) > 0 :
|
||||
args3 = ["lspci", "-vvs"]
|
||||
args3.append(pciAddr)
|
||||
pipe3 = subprocess.Popen(args3, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output3 = pipe3.stdout.readlines()
|
||||
pciStatusClock = ""
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output3]:
|
||||
words = line.split(":")
|
||||
if len(words) == 2 :
|
||||
keyWord = words[0].strip()
|
||||
valWord = words[1].strip()
|
||||
if keyWord == "Status" :
|
||||
result = re.findall("[\s]*([0-9]+MHz)-.*", valWord)
|
||||
if result and len(result) > 0 :
|
||||
pciStatusClock = result[0]
|
||||
if len(pciStatusClock) > 0 :
|
||||
summary["list"][index][AudioAdaptor_Clock] = pciStatusClock
|
||||
|
||||
index += 1
|
||||
|
||||
if len(summary["list"]) == 0 :
|
||||
# non-pci bus
|
||||
sound_card_paths = glob.glob('/sys/class/sound/card*')
|
||||
for sound_card_path in sound_card_paths:
|
||||
card_num = sound_card_path.split('/')[-1][4:]
|
||||
driver_path = sound_card_path + '/device/driver'
|
||||
driver_realpath_split = os.path.realpath(driver_path).split('/')
|
||||
# /sys/bus/platform/drivers/hisi-dp-audio
|
||||
bus_type = driver_realpath_split[3]
|
||||
if bus_type == 'platform':# soc devices
|
||||
audioAdaptor = {}
|
||||
audioAdaptor[AudioAdaptor_Businfo] = bus_type
|
||||
vendor = ''
|
||||
product = 'Soc Integrated'
|
||||
compatible_path = sound_card_path + "/device/of_node/compatible"
|
||||
codec_path = "/proc/asound/card%s/codec#0" % card_num
|
||||
if os.path.exists(codec_path):
|
||||
#Name:da_combine_v5
|
||||
#Vendor:HISILICON
|
||||
#Model:da_combine_v5
|
||||
with open(codec_path, 'r') as f:
|
||||
line = f.readline()
|
||||
while line:
|
||||
if line.startswith('Name:'):
|
||||
product = line.strip().split(':', 1)[-1]
|
||||
elif line.startswith('Vendor:'):
|
||||
vendor = line.strip().split(':', 1)[-1]
|
||||
line = f.readline()
|
||||
elif os.path.exists(compatible_path):
|
||||
# hisilicon,hisi-dp-audio-machine\x00
|
||||
with open(compatible_path, 'r') as f:
|
||||
compatible_content_split = f.read().split(',')
|
||||
vendor = compatible_content_split[0]
|
||||
product = compatible_content_split[1].strip()
|
||||
flag_9a0 = Judgment_HW9A0()
|
||||
if flag_9a0 and "da_combine_v5" in product:
|
||||
product = "Hi6405"
|
||||
audioAdaptor[AudioAdaptor_Product] = mystrip(product)
|
||||
flag_pangu = Judgment_PANGUW()
|
||||
if flag_pangu and "Audio" in vendor:
|
||||
vendor = "HUAWEI"
|
||||
if len(vendor) > 0 :
|
||||
audioAdaptor[AudioAdaptor_Manufacturer] = get_url(mystrip(vendor), mystrip(vendor))
|
||||
driver_name = driver_realpath_split[-1]
|
||||
audioAdaptor[AudioAdaptor_Driver] = driver_name
|
||||
if AudioAdaptor_Manufacturer in audioAdaptor :
|
||||
summary["list"].append(audioAdaptor)
|
||||
else:
|
||||
# pci bus devices have been parsed
|
||||
# other bus device is unsupported
|
||||
pass
|
||||
|
||||
if len(summary["list"]) == 0 :
|
||||
return ""
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getAudioAdaptorInfo()
|
||||
if len(outLine) == 0 :
|
||||
return ""
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if AudioAdaptor_Product in info and len(info[AudioAdaptor_Product]) > 0:
|
||||
if nIndex == 0 :
|
||||
outLine += info[AudioAdaptor_Product]
|
||||
else :
|
||||
outLine += " / " + info[AudioAdaptor_Product]
|
||||
elif AudioAdaptor_Model in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[AudioAdaptor_Model]
|
||||
else :
|
||||
outLine += " / " + info[AudioAdaptor_Model]
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = AudioAdaptor(cmdTool)
|
||||
pprint(cc.getAudioAdaptorInfo())
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
|
||||
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<!-- Only root can own the service -->
|
||||
<policy user="root">
|
||||
<allow own="com.kylin.assistant.systemdaemon"/>
|
||||
<allow send_interface="com.kylin.assistant.systemdaemon"/>
|
||||
</policy>
|
||||
|
||||
<!-- Allow anyone to invoke methods on the interfaces -->
|
||||
<policy context="default">
|
||||
<allow send_destination="com.kylin.assistant.systemdaemon"
|
||||
send_interface="com.kylin.assistant.systemdaemon"/>
|
||||
<allow send_destination="com.kylin.assistant.systemdaemon"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
<allow send_destination="com.kylin.assistant.systemdaemon"
|
||||
send_interface="org.freedesktop.DBus.Properties"/>
|
||||
</policy>
|
||||
</busconfig>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
|
||||
<vendor>Kylin Assistant</vendor>
|
||||
<vendor_url>https://www.kylinos.cn/</vendor_url>
|
||||
<icon_name>kylin-assistant</icon_name>
|
||||
|
||||
<action id="com.kylin.assistant.systemdaemon.action">
|
||||
<_description>
|
||||
system level settings
|
||||
</_description>
|
||||
<_message>
|
||||
To Change the settings, you need to authenticate.
|
||||
</_message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin</allow_any>
|
||||
<allow_inactive>auth_admin</allow_inactive>
|
||||
<allow_active>auth_admin</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
|
@ -0,0 +1,4 @@
|
|||
[D-BUS Service]
|
||||
Name=com.kylin.assistant.systemdaemon
|
||||
Exec=/usr/bin/kylin-assistant-systemdaemon.py
|
||||
User=root
|
|
@ -0,0 +1,161 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from systemboardthread import *
|
||||
|
||||
|
||||
class KABatteryInfo():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getBatteryInfo(self, sysProductName = ""):
|
||||
summary = {"list":[]}
|
||||
|
||||
args = ["upower", "--dump"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
oddindex = -1
|
||||
pattern = re.compile(r'Device: ')
|
||||
batSerailNum,batState,batPercentage,batTimeToEmpty,batEnergyFull,batEnergy,batUsedTimes,batManufacturer,batModel,batSupply = \
|
||||
"","","","","","","","","",False
|
||||
batOne = {}
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
if pattern.match(line):
|
||||
if "battery" in line.lower() :
|
||||
oddindex = 1
|
||||
else :
|
||||
oddindex = -1
|
||||
|
||||
if len(batOne) > 0 and batSupply :
|
||||
if len(sysProductName) > 0 :
|
||||
if "TN140A2" in sysProductName or "TN133A2" in sysProductName : ##长城笔记本
|
||||
# batOne[BTI_MANUFACTURER] = "飞毛腿(福建)电子有限公司"
|
||||
# batOne[BTI_MODEL] = "SNGW001"
|
||||
batOne[BTI_ENERGY] = ""
|
||||
batOne[BTI_ENERGYFULL] = "60Wh"
|
||||
elif "F860-T1" in sysProductName : ##清华同方笔记本
|
||||
batOne[BTI_MANUFACTURER] = "飞毛腿"
|
||||
batOne[BTI_MODEL] = "SNBL001"
|
||||
batOne[BTI_ENERGY] = ""
|
||||
batOne[BTI_ENERGYFULL] = "63Wh"
|
||||
if BTI_MANUFACTURER not in batOne :
|
||||
batOne[BTI_NAME] = "Name"
|
||||
summary["list"].append(batOne)
|
||||
batSerailNum,batState,batPercentage,batTimeToEmpty,batEnergyFull,batEnergy,batUsedTimes,batManufacturer,batModel,batSupply = \
|
||||
"","","","","","","","","",False
|
||||
batOne = {}
|
||||
else:
|
||||
if oddindex == -1:
|
||||
continue
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
results = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
#厂商
|
||||
if line.startswith("vendor:") and "kylin" != results[1] :
|
||||
batManufacturer = results[1]
|
||||
#序列号
|
||||
if line.startswith("serial:") and len(results[1]) > 0 and "0" != results[1] and "None" != results[1]:
|
||||
batSerailNum = results[1]
|
||||
#型号
|
||||
if line.startswith("model:"):
|
||||
batModel = results[1]
|
||||
#状态
|
||||
if line.startswith("state:"):
|
||||
batState = results[1]
|
||||
#电量
|
||||
if line.startswith("percentage:"):
|
||||
batPercentage = results[1]
|
||||
#当前容量
|
||||
if line.startswith("energy:"):
|
||||
batEnergy = results[1]
|
||||
#满电容量
|
||||
if line.startswith("energy-full:"):
|
||||
batEnergyFull = results[1]
|
||||
#预计使用时间
|
||||
if line.startswith("time to empty:"):
|
||||
batTimeToEmpty = results[1]
|
||||
#是否供电
|
||||
if line.startswith("power supply:"):
|
||||
if results[1] == "yes" :
|
||||
batSupply = True
|
||||
else :
|
||||
batSupply = False
|
||||
|
||||
if len(batManufacturer) > 0 :
|
||||
batOne[BTI_MANUFACTURER] = batManufacturer
|
||||
if len(batSerailNum) > 0 :
|
||||
batOne[BTI_SERAILNUM] = batSerailNum
|
||||
if len(batState) > 0 :
|
||||
batOne[BTI_STATE] = batState
|
||||
if len(batPercentage) > 0 :
|
||||
batOne[BTI_PERCENTAGE] = batPercentage
|
||||
if len(batEnergy) > 0 :
|
||||
batOne[BTI_ENERGY] = batEnergy
|
||||
if len(batEnergyFull) > 0 :
|
||||
batOne[BTI_ENERGYFULL] = batEnergyFull
|
||||
if len(batTimeToEmpty) > 0 :
|
||||
batOne[BTI_TTE] = batTimeToEmpty
|
||||
if len(batUsedTimes) > 0 :
|
||||
batOne[BTI_USEDTIMES] = batUsedTimes
|
||||
if len(batModel) > 0 :
|
||||
batOne[BTI_MODEL] = batModel
|
||||
if len(batOne) > 0 and batSupply :
|
||||
if len(sysProductName) > 0 :
|
||||
if "TN140A2" in sysProductName : ##长城笔记本
|
||||
batOne[BTI_MANUFACTURER] = "飞毛腿(福建)电子有限公司"
|
||||
batOne[BTI_MODEL] = "SNGW001"
|
||||
batOne[BTI_ENERGY] = ""
|
||||
batOne[BTI_ENERGYFULL] = "60Wh"
|
||||
elif "F860-T1" in sysProductName : ##清华同方笔记本
|
||||
batOne[BTI_MANUFACTURER] = "飞毛腿"
|
||||
batOne[BTI_MODEL] = "SNBL001"
|
||||
batOne[BTI_ENERGY] = ""
|
||||
batOne[BTI_ENERGYFULL] = "63Wh"
|
||||
if BTI_MANUFACTURER not in batOne :
|
||||
batOne[BTI_NAME] = "Name"
|
||||
summary["list"].append(batOne)
|
||||
if len(summary["list"]) == 0:
|
||||
return ""
|
||||
return json.dumps(summary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KABatteryInfo()
|
||||
pprint(cc.getBatteryInfo())
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
class KABluetoothInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getBluetoothInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
baseList = self.cmdTool.loadInfoFromHciconfig()
|
||||
hwinfoList = self.cmdTool.loadInfoFromHwinfo("--usb")["list"]
|
||||
length = len(baseList)
|
||||
for i in range(length) :
|
||||
if len(baseList[i]) == 0 :
|
||||
continue
|
||||
for mapInfo in hwinfoList :
|
||||
if len(mapInfo) == 0 :
|
||||
continue
|
||||
if "Hardware Class" not in mapInfo :
|
||||
continue
|
||||
if mapInfo["Hardware Class"] == "hub" or mapInfo["Hardware Class"] == "mouse" or mapInfo["Hardware Class"] == "keyboard" :
|
||||
continue
|
||||
if mapInfo["Hardware Class"] == "bluetooth" or ("Driver" in mapInfo and mapInfo["Driver"] == "btusb") \
|
||||
or ("Device" in mapInfo and mapInfo["Device"] == "BCM20702A0") :
|
||||
if "Vendor" in mapInfo and len(mapInfo["Vendor"]) > 0 :
|
||||
words = mapInfo["Vendor"].split(" ")
|
||||
if len(words) < 1 :
|
||||
continue
|
||||
if "Manufacturer" in baseList[i] and len(baseList[i]["Manufacturer"]) > 0 :
|
||||
if words[0] not in baseList[i]["Manufacturer"] :
|
||||
continue
|
||||
baseList[i].update(mapInfo)
|
||||
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
lshwinfoList = self.cmdTool.lshwUsbList
|
||||
for i in range(length) :
|
||||
if len(baseList[i]) == 0 :
|
||||
continue
|
||||
if "SysFS BusID" not in baseList[i] :
|
||||
continue
|
||||
for mapInfo in lshwinfoList :
|
||||
if len(mapInfo) == 0 :
|
||||
continue
|
||||
if "bus info" in mapInfo :
|
||||
words = mapInfo["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip()
|
||||
#key = key.replace(".","" in mapInfo
|
||||
if key != baseList[i]["SysFS BusID"] :
|
||||
continue
|
||||
baseList[i].update(mapInfo)
|
||||
|
||||
index = 0
|
||||
for mapInfo in baseList :
|
||||
summary["list"].append({})
|
||||
##名称
|
||||
if "product" in mapInfo :
|
||||
summary["list"][index][BLI_PRODUCT] = mapInfo["product"]
|
||||
|
||||
##制造商
|
||||
if "Manufacturer" in mapInfo :
|
||||
summary["list"][index][BLI_MANUFACTURER] = mapInfo["Manufacturer"]
|
||||
|
||||
if "Vendor" in mapInfo :
|
||||
summary["list"][index][BLI_MANUFACTURER] = mapInfo["Vendor"]
|
||||
|
||||
if "vendor" in mapInfo :
|
||||
summary["list"][index][BLI_MANUFACTURER] = mapInfo["vendor"]
|
||||
|
||||
##类型
|
||||
if "description" in mapInfo :
|
||||
summary["list"][index][BLI_DEVTYPE] = mapInfo["description"]
|
||||
|
||||
##版本
|
||||
if "Revision" in mapInfo :
|
||||
summary["list"][index][BLI_DEVVERSION] = mapInfo["Revision"]
|
||||
if "version" in mapInfo :
|
||||
summary["list"][index][BLI_DEVVERSION] = mapInfo["version"]
|
||||
|
||||
##总线信息
|
||||
if "bus info" in mapInfo :
|
||||
summary["list"][index][BLI_BUSADDR] = mapInfo["bus info"]
|
||||
|
||||
##驱动
|
||||
if "driver" in mapInfo :
|
||||
summary["list"][index][BLI_DRIVER] = mapInfo["driver"]
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
summary["list"][index][BLI_DEVMODEL] = mapInfo["Model"].strip("\"")
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
summary["list"][index][BLI_DRIVER] = mapInfo["Driver"].strip("\"")
|
||||
|
||||
##速度
|
||||
if "Speed" in mapInfo :
|
||||
summary["list"][index][BLI_SPEED] = mapInfo["Speed"]
|
||||
if "speed" in mapInfo :
|
||||
summary["list"][index][BLI_SPEED] = mapInfo["speed"]
|
||||
|
||||
##序列号
|
||||
if "Serial ID" in mapInfo :
|
||||
summary["list"][index][BLI_SERIALNUM] = mapInfo["Serial ID"].strip("\"")
|
||||
|
||||
##名称
|
||||
if "Name" in mapInfo :
|
||||
summary["list"][index][BLI_NAME] = mapInfo["Name"].strip("\'")
|
||||
|
||||
##名称
|
||||
if "BD Address" in mapInfo :
|
||||
summary["list"][index][BLI_ADDRESS] = mapInfo["BD Address"]
|
||||
|
||||
##功能
|
||||
if "capabilities" in mapInfo :
|
||||
summary["list"][index][BLI_CAPABILITIES] = mapInfo["capabilities"]
|
||||
|
||||
##总线
|
||||
if "Bus" in mapInfo :
|
||||
summary["list"][index][BLI_BUS] = mapInfo["Bus"]
|
||||
|
||||
##SCO MTU
|
||||
if "SCO MTU" in mapInfo :
|
||||
summary["list"][index][BLI_SCOMTU] = mapInfo["SCO MTU"]
|
||||
|
||||
##ALC MTU
|
||||
if "ACL MTU" in mapInfo :
|
||||
summary["list"][index][BLI_ALCMTU] = mapInfo["ACL MTU"]
|
||||
|
||||
##数据包类型
|
||||
if "Packet type" in mapInfo :
|
||||
summary["list"][index][BLI_PACKETTYPE] = mapInfo["Packet type"]
|
||||
|
||||
##特征
|
||||
if "Features" in mapInfo :
|
||||
summary["list"][index][BLI_FEATURES] = mapInfo["Features"]
|
||||
|
||||
##连接模式
|
||||
if "Link mode" in mapInfo :
|
||||
summary["list"][index][BLI_LINKMODE] = mapInfo["Link mode"]
|
||||
|
||||
##连接策略
|
||||
if "Link policy" in mapInfo :
|
||||
summary["list"][index][BLI_LINKPOLICY] = mapInfo["Link policy"]
|
||||
|
||||
index += 1
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getBluetoothInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if BLI_NAME in info and len(info[BLI_NAME]) > 0:
|
||||
if nIndex == 0 :
|
||||
outLine += info[BLI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[BLI_NAME]
|
||||
elif BLI_DEVMODEL in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[BLI_DEVMODEL]
|
||||
else :
|
||||
outLine += " / " + info[BLI_DEVMODEL]
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdtool = KACmdTool()
|
||||
cmdtool.loadInfoFromLshw()
|
||||
cc = KABluetoothInfo(cmdtool)
|
||||
pprint(cc.getBluetoothInfo())
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
class KACameraInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getCameraInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
hwinfoList = self.cmdTool.loadInfoFromHwinfo("--usb")["list"]
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
lshwInfoList = self.cmdTool.lshwUsbList
|
||||
validInfoList = []
|
||||
length = len(hwinfoList)
|
||||
for i in range(length) :
|
||||
if len(hwinfoList[i]) < 5 :
|
||||
continue
|
||||
if "SysFS BusID" not in hwinfoList[i] :
|
||||
continue
|
||||
if ("Model" in hwinfoList[i] and "camera" in hwinfoList[i]["Model"].lower()) or \
|
||||
("Device" in hwinfoList[i] and "camera" in hwinfoList[i]["Device"].lower()) or \
|
||||
("Driver" in hwinfoList[i] and "uvcvideo" in hwinfoList[i]["Driver"].lower()) or \
|
||||
("Model" in hwinfoList[i] and "webcam" in hwinfoList[i]["Model"].lower()) :
|
||||
## 获取映射到 lshw设备信息的 关键字
|
||||
##1-4:1.0
|
||||
words = hwinfoList[i]["SysFS BusID"].split(":")
|
||||
if len(words) == 2 :
|
||||
chs = words[0].split("-")
|
||||
if len(words) == 2 :
|
||||
keyToLshw = "usb@"+chs[0]+":"+chs[1]
|
||||
for mapInfo in lshwInfoList :
|
||||
if "bus info" in mapInfo and mapInfo["bus info"] == keyToLshw :
|
||||
hwinfoList[i].update(mapInfo)
|
||||
validInfoList.append(hwinfoList[i])
|
||||
|
||||
for mapInfo in validInfoList :
|
||||
if len(mapInfo) < 5 :
|
||||
continue
|
||||
caOne = {}
|
||||
caName,caManufacturer,caModel,caInterface,caDriver,caType,caVersion,caBus,caSpeed = "","","","","","","","",""
|
||||
##名称
|
||||
if "Device" in mapInfo :
|
||||
caDevice = mapInfo["Device"].split("\"")
|
||||
if len(caDevice) > 1 :
|
||||
caName = caDevice[1]
|
||||
else :
|
||||
caName = mapInfo["Device"]
|
||||
if "product" in mapInfo :
|
||||
caName = mapInfo["product"]
|
||||
##类型
|
||||
if "Hardware Class" in mapInfo and "unknown" not in mapInfo["Hardware Class"] :
|
||||
caType = mapInfo["Hardware Class"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
caVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(caVendor) > 1 :
|
||||
caManufacturer = caVendor[1]
|
||||
else :
|
||||
caManufacturer = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
caVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(caVendor) > 1 :
|
||||
caManufacturer = caVendor[1]
|
||||
else :
|
||||
caManufacturer = mapInfo["SubVendor"]
|
||||
if "vendor" in mapInfo :
|
||||
caManufacturer = mapInfo["vendor"]
|
||||
|
||||
##接口
|
||||
if "Hotplug" in mapInfo :
|
||||
caInterface = mapInfo["Hotplug"]
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
caModel = mapInfo["Model"].strip("\"")
|
||||
if "bluetooth" in caModel :
|
||||
caInterface = "BLUETOOTH"
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
caDriver = mapInfo["Driver"].strip("\"")
|
||||
|
||||
##总线
|
||||
if "SysFS BusID" in mapInfo :
|
||||
caBus = mapInfo["SysFS BusID"]
|
||||
|
||||
##版本
|
||||
if "Revision" in mapInfo :
|
||||
caVersion = mapInfo["Revision"]
|
||||
if "version" in mapInfo :
|
||||
caVersion = mapInfo["version"]
|
||||
|
||||
##速度
|
||||
if "Speed" in mapInfo :
|
||||
caSpeed = mapInfo["Speed"]
|
||||
if "speed" in mapInfo :
|
||||
caSpeed = mapInfo["speed"]
|
||||
|
||||
if len(caName) > 0 :
|
||||
caOne[CAI_NAME] = caName
|
||||
if len(caManufacturer) > 0 :
|
||||
caOne[CAI_MANUFACTURER] = caManufacturer
|
||||
if len(caModel) > 0 :
|
||||
caOne[CAI_MODEL] = caModel
|
||||
if len(caInterface) > 0 :
|
||||
caOne[CAI_INTERFACE] = caInterface
|
||||
if len(caDriver) > 0 :
|
||||
caOne[CAI_DRIVER] = caDriver
|
||||
if len(caType) > 0 :
|
||||
caOne[CAI_TYPE] = caType
|
||||
if len(caVersion) > 0 :
|
||||
caOne[CAI_VERSION] = caVersion
|
||||
if len(caBus) > 0 :
|
||||
caOne[CAI_BUSINFO] = caBus
|
||||
if len(caSpeed) > 0 :
|
||||
caOne[CAI_SPEED] = caSpeed
|
||||
|
||||
if len(caOne) > 0 :
|
||||
summary["list"].append(caOne)
|
||||
if len(summary["list"]) == 0:
|
||||
return ""
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getMouseInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if CAI_NAME in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[CAI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[CAI_NAME]
|
||||
if CAI_MODEL in info :
|
||||
outLine += "("+info[CAI_MODEL]+")"
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = KACameraInfo(cmdTool)
|
||||
pprint(cc.getCameraInfo())
|
||||
#pprint(cc.getOutline())
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
class KACDRomInfo():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getCDRomInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
args = ["hwinfo", "--cdrom"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
oddindex = -1
|
||||
pattern = re.compile(r'^\d+: ')
|
||||
cdRomName,cdRomManufacturer,cdRomModel,cdRomVersion,cdRomBusInfo,cdRomDriver, \
|
||||
cdRomSpeed,cdRomSerialNum,cdRomDeviceNum = "","","","","","","","",""
|
||||
cdRomOne = {}
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
if pattern.match(line):
|
||||
oddindex += 1
|
||||
if len(cdRomOne) > 0 :
|
||||
summary["list"].append(cdRomOne)
|
||||
cdRomName,cdRomManufacturer,cdRomModel,cdRomVersion,cdRomBusInfo,cdRomDriver, \
|
||||
cdRomSpeed,cdRomSerialNum,cdRomDeviceNum = "","","","","","","","",""
|
||||
cdRomOne = {}
|
||||
else:
|
||||
if oddindex == -1:
|
||||
continue
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
results = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
#名称
|
||||
if line.startswith("Device:"):
|
||||
cdDevice = results[1].split("\"")
|
||||
if len(cdDevice) > 1 :
|
||||
cdRomName = cdDevice[1]
|
||||
else :
|
||||
cdRomName = results[1]
|
||||
#制造商
|
||||
if line.startswith("Vendor:"):
|
||||
cdVendor = results[1].split("\"")
|
||||
if len(cdVendor) > 1 :
|
||||
cdRomManufacturer = cdVendor[1]
|
||||
else :
|
||||
cdRomManufacturer = results[1]
|
||||
if line.startswith("SubVendor:"):
|
||||
cdVendor = results[1].split("\"")
|
||||
if len(cdVendor) > 1 :
|
||||
cdRomManufacturer = cdVendor[1]
|
||||
else :
|
||||
cdRomManufacturer = results[1]
|
||||
#版本
|
||||
if line.startswith("Revision:"):
|
||||
cdRomVersion = results[1].strip("\"")
|
||||
|
||||
#型号
|
||||
if line.startswith("Model:"):
|
||||
cdRomModel = results[1].strip("\"")
|
||||
#总线信息
|
||||
if line.startswith("SysFS BusID:"):
|
||||
cdRomBusInfo = results[1]
|
||||
#驱动
|
||||
if line.startswith("Driver:"):
|
||||
cdDriver = results[1].split("\"")
|
||||
if len(cdDriver) > 1 :
|
||||
cdRomDriver = cdDriver[1]
|
||||
else :
|
||||
cdRomDriver = results[1].strip("\"")
|
||||
#速度
|
||||
if line.startswith("Speed:"):
|
||||
cdRomSpeed = results[1]
|
||||
#序列号
|
||||
if line.startswith("Serial ID:"):
|
||||
cdRomSerialNum = results[1].strip("\"")
|
||||
#设备编号
|
||||
if line.startswith("Device Number:"):
|
||||
cdRomDeviceNum = results[1]
|
||||
|
||||
if len(cdRomName) > 0 :
|
||||
cdRomOne[CDI_NAME] = cdRomName
|
||||
if len(cdRomManufacturer) > 0 :
|
||||
cdRomOne[CDI_MANUFACTURER] = cdRomManufacturer
|
||||
if len(cdRomModel) > 0 :
|
||||
cdRomOne[CDI_MODEL] = cdRomModel
|
||||
if len(cdRomVersion) > 0 :
|
||||
cdRomOne[CDI_VERSION] = cdRomVersion
|
||||
if len(cdRomBusInfo) > 0 :
|
||||
cdRomOne[CDI_BUSINFO] = cdRomBusInfo
|
||||
if len(cdRomDriver) > 0 :
|
||||
cdRomOne[CDI_DRIVER] = cdRomDriver
|
||||
if len(cdRomSpeed) > 0 :
|
||||
cdRomOne[CDI_SPEED] = cdRomSpeed
|
||||
if len(cdRomSerialNum) > 0 :
|
||||
cdRomOne[CDI_SERAILNUM] = cdRomSerialNum
|
||||
if len(cdRomDeviceNum) > 0 :
|
||||
cdRomOne[CDI_DEVICENUM] = cdRomDeviceNum
|
||||
if len(cdRomOne) > 0 :
|
||||
summary["list"].append(cdRomOne)
|
||||
return json.dumps(summary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KACDRomInfo()
|
||||
pprint(cc.getCDRomInfo())
|
||||
|
|
@ -0,0 +1,802 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
|
||||
class KACmdTool():
|
||||
|
||||
def __init__(self):
|
||||
self.lshwSystemList = []
|
||||
self.lshwDiskList = []
|
||||
self.lshwCpuList = []
|
||||
self.lshwStorageList = []
|
||||
self.lshwMemoryList = []
|
||||
self.lshwDisplayList = []
|
||||
self.lshwMultimediaList = []
|
||||
self.lshwNetworkList = []
|
||||
self.lshwUsbList = []
|
||||
self.lshwCDRomList = []
|
||||
self.lsblkSmartList = []
|
||||
self.dmesgGPUList = []
|
||||
self.nvidiaGpuList = []
|
||||
self.pacmdSoundList = []
|
||||
pass
|
||||
|
||||
def loadHwinfoUsbinfo(self, info, summary, mapInfo):
|
||||
add = True
|
||||
for item in summary:
|
||||
if "SysFS BusID" in item:
|
||||
curBus = item["SysFS BusID"]
|
||||
newBus = mapInfo["SysFS BusID"]
|
||||
curBus = re.sub("\\.[0-9]{1,2}$", "", curBus)
|
||||
newBus = re.sub("\\.[0-9]{1,2}$", "", newBus)
|
||||
if curBus == newBus :
|
||||
add = False
|
||||
break
|
||||
## 这个是用来过滤,没有接入任何设备的usb接口
|
||||
if "Model" in mapInfo and "Linux Foundation" in mapInfo["Model"] :
|
||||
add = False
|
||||
|
||||
if "Hardware Class" in mapInfo and "hub".lower() in mapInfo["Hardware Class"].lower() :
|
||||
add = False
|
||||
|
||||
## 打印机几信息不从hwinfo --usb里面获取,需要过滤
|
||||
if "Printer".lower() in info.lower() or "LaserJet".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
## 提前过滤掉键盘鼠标
|
||||
if "mouse".lower() in info.lower() or "keyboard".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
if "Wacom".lower() in info.lower() :
|
||||
add = False
|
||||
|
||||
if add :
|
||||
summary["list"].append(mapInfo)
|
||||
|
||||
def loadInfoFromHwinfo(self, param):
|
||||
summary = {"list":[]}
|
||||
|
||||
args = ["hwinfo", param]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
result = bytes.decode(l, "utf-8", "ignore")
|
||||
if result :
|
||||
allinfo += result
|
||||
|
||||
infoList = allinfo.split("\n\n")
|
||||
for info in infoList:
|
||||
if len(info) != 0 :
|
||||
mapInfo = {}
|
||||
infoLines = info.split("\n")
|
||||
for line in infoLines:
|
||||
words = line.split(": ")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
keyInfo = words[0].strip()
|
||||
if keyInfo in mapInfo:
|
||||
mapInfo[keyInfo] += " "
|
||||
result = re.findall(".*\"(.*)\".*", words[1])
|
||||
if result and len(result) > 0 :
|
||||
key = keyInfo
|
||||
value = result[0]
|
||||
##这里是为了防止 "usb-storage", "sr" -》 usb-storage", "sr
|
||||
if key == "Driver" :
|
||||
value = value.replace("\"", "");
|
||||
if key in mapInfo :
|
||||
mapInfo[key] += value;
|
||||
else :
|
||||
mapInfo[key] = value;
|
||||
else :
|
||||
if keyInfo == "Resolution" and keyInfo in mapInfo :
|
||||
mapInfo[keyInfo] += words[1].strip();
|
||||
else :
|
||||
mapInfo[keyInfo] = words[1].strip();
|
||||
|
||||
if "Vendor" == keyInfo :
|
||||
result = re.findall("usb 0x([0-9]*)", words[1])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["usb_vendor"] = result[0]
|
||||
elif "Device" == keyInfo :
|
||||
result = re.findall("usb 0x([0-9]*)", words[1])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["usb_device"] = result[0]
|
||||
|
||||
if "--usb" == param :
|
||||
self.loadHwinfoUsbinfo(info, summary, mapInfo)
|
||||
elif "--keyboard" == param or "--mouse" == param :
|
||||
if "Linux Foundation" not in info and "Elite Remote Control Driver" not in info \
|
||||
and "Model: \"serial console\"" not in info and "Wacom".lower() not in info.lower() :
|
||||
summary["list"].append(mapInfo)
|
||||
else :
|
||||
summary["list"].append(mapInfo)
|
||||
return summary
|
||||
|
||||
def loadDiskInfoFromSmart(self, devName, mapInfo) :
|
||||
indexName = ""
|
||||
|
||||
args = ["smartctl", "--all", "/dev/"+devName]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infos = allinfo.split("\n")
|
||||
for line in infos:
|
||||
if len(line) > 0 :
|
||||
index = line.find(": ")
|
||||
if index > 0 and not re.findall("^[\s\S]*[\d]:[\d][\s\S]*$", line) and "Error" not in line and "hh:mm:SS" not in line :
|
||||
if line.find("(") < index and line.find(")") > index :
|
||||
continue
|
||||
if line.find("[") < index and line.find("]") > index :
|
||||
continue
|
||||
words = line.split(": ")
|
||||
if len(words) != 2 and "SATA Version is" not in words :
|
||||
continue
|
||||
indexName = words[0].strip().replace(" is", "")
|
||||
if indexName in mapInfo :
|
||||
mapInfo[indexName] += ", "
|
||||
mapInfo[indexName] += words[1].strip()
|
||||
else :
|
||||
mapInfo[indexName] = words[1].strip()
|
||||
continue
|
||||
|
||||
if len(indexName) > 0 and (line.startswith("\t\t") or line.startswith(" ")) and ":" not in line :
|
||||
if indexName in mapInfo :
|
||||
mapInfo[indexName] += ", "
|
||||
mapInfo[indexName] += line.strip()
|
||||
else :
|
||||
mapInfo[indexName] = line.strip()
|
||||
continue
|
||||
|
||||
indexName = ""
|
||||
# 1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
|
||||
result = re.findall("\s*[0-9]+\s+([\w\_]+)\s+0x[0-9a-fA-F\-]+\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[\w]+\s+[\w]+\s+[\w\-]+\s+([0-9]+)$", line)
|
||||
if result and len(result) > 0:
|
||||
mapInfo[result[0][0]] = result[0][1]
|
||||
continue;
|
||||
|
||||
strList = []
|
||||
if line.endswith(")") :
|
||||
leftBracket = line.find("(")
|
||||
if leftBracket > 0 :
|
||||
key = line[:leftBracket].strip()
|
||||
strList = key.split(" ")
|
||||
if len(strList) > 2 :
|
||||
strList[-1] += line[leftBracket:]
|
||||
elif len(strList) == 0 :
|
||||
strList = line.strip().split(" ")
|
||||
|
||||
if len(strList) < 5 :
|
||||
continue
|
||||
|
||||
if "Power_On_Hours" in line :
|
||||
mapInfo["Power_On_Hours"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Power_Cycle_Count" in line :
|
||||
mapInfo["Power_Cycle_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Raw_Read_Error_Rate" in line :
|
||||
mapInfo["Raw_Read_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Spin_Up_Time" in line :
|
||||
mapInfo["Spin_Up_Time"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Start_Stop_Count" in line :
|
||||
mapInfo["Start_Stop_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Reallocated_Sector_Ct" in line :
|
||||
mapInfo["Reallocated_Sector_Ct"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Seek_Error_Rate" in line :
|
||||
mapInfo["Seek_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Spin_Retry_Count" in line :
|
||||
mapInfo["Spin_Retry_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Calibration_Retry_Count" in line :
|
||||
mapInfo["Calibration_Retry_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "G-Sense_Error_Rate" in line :
|
||||
mapInfo["G-Sense_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Power-Off_Retract_Count" in line :
|
||||
mapInfo["Power-Off_Retract_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Load_Cycle_Count" in line :
|
||||
mapInfo["Load_Cycle_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Temperature_Celsius" in line :
|
||||
mapInfo["Temperature_Celsius"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Reallocated_Event_Count" in line :
|
||||
mapInfo["Reallocated_Event_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Current_Pending_Sector" in line :
|
||||
mapInfo["Current_Pending_Sector"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Offline_Uncorrectable" in line :
|
||||
mapInfo["Offline_Uncorrectable"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "UDMA_CRC_Error_Count" in line :
|
||||
mapInfo["UDMA_CRC_Error_Count"] = strList[-1];
|
||||
continue
|
||||
|
||||
if "Multi_Zone_Error_Rate" in line :
|
||||
mapInfo["Multi_Zone_Error_Rate"] = strList[-1];
|
||||
continue
|
||||
|
||||
return mapInfo
|
||||
|
||||
def loadDiskInfoFromLsblk(self) :
|
||||
args = ["lsblk", "-d", "-o", "name,rota,rm,maj:min"]
|
||||
pipe = subprocess.Popen(args, env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
lines = allinfo.split("\n");
|
||||
for line in lines :
|
||||
words = re.sub("[\s]+", " ", line).strip().split(" ")
|
||||
if len(words) != 4 or words[0] == "NAME" :
|
||||
continue
|
||||
mapInfo = {}
|
||||
mapInfo["dev_name"] = words[0].strip()
|
||||
mapInfo["dev_rota"] = words[1].strip()
|
||||
mapInfo["dev_removeable"] = words[2].strip()
|
||||
mapInfo["dev_majmin"] = words[3].strip()
|
||||
self.loadDiskInfoFromSmart(words[0].strip(), mapInfo)
|
||||
self.lsblkSmartList.append(mapInfo)
|
||||
pass
|
||||
|
||||
def getInfoFromLshw(self, info, mapInfo) :
|
||||
infoList = info.split("\n")
|
||||
for infoItem in infoList:
|
||||
words = infoItem.split(": ")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
if "configuration" in words[0] :
|
||||
keyValues = words[1].split(" ")
|
||||
for keyValue in keyValues :
|
||||
attr = keyValue.split("=")
|
||||
if len(attr) != 2 :
|
||||
continue
|
||||
mapInfo[attr[0].strip()] = attr[1].strip()
|
||||
elif "resources" in words[0] :
|
||||
keyValues = words[1].split(" ")
|
||||
for keyValue in keyValues:
|
||||
attr = keyValue.split(":")
|
||||
if len(attr) != 2 :
|
||||
continue
|
||||
if attr[0].strip() in mapInfo :
|
||||
mapInfo[attr[0].strip()] += " "+attr[1].strip()
|
||||
else :
|
||||
mapInfo[attr[0].strip()] = attr[1].strip()
|
||||
else :
|
||||
mapInfo[words[0].strip()] = words[1].strip()
|
||||
|
||||
|
||||
def loadInfoFromLshw(self, forceLoad = True):
|
||||
if not forceLoad and len(self.lshwSystemList) > 0 :
|
||||
return
|
||||
|
||||
args = ["lshw"]
|
||||
pipe = subprocess.Popen(args, env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
items = allinfo.split("*-");
|
||||
isFirst = True
|
||||
self.lshwSystemList = []
|
||||
self.lshwDiskList = []
|
||||
self.lshwCpuList = []
|
||||
self.lshwStorageList = []
|
||||
self.lshwMemoryList = []
|
||||
self.lshwDisplayList = []
|
||||
self.lshwMultimediaList = []
|
||||
self.lshwNetworkList = []
|
||||
self.lshwUsbList = []
|
||||
self.lshwCDRomList = []
|
||||
for item in items :
|
||||
if len(item) > 0 :
|
||||
mapInfo = {}
|
||||
if isFirst :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwSystemList.append(mapInfo)
|
||||
isFirst = False
|
||||
continue
|
||||
if item.startswith("cpu") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwCpuList.append(mapInfo)
|
||||
elif item.startswith("disk") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwDiskList.append(mapInfo)
|
||||
elif item.startswith("storage") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwStorageList.append(mapInfo)
|
||||
elif (item.startswith("memory") and not item.startswith("memory UNCLAIMED")) or item.startswith("bank") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwMemoryList.append(mapInfo)
|
||||
elif item.startswith("display") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwDisplayList.append(mapInfo)
|
||||
elif item.startswith("multimedia") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwMultimediaList.append(mapInfo)
|
||||
elif item.startswith("network") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
if not re.findall(".*network:[0-9] DISABLED.*", item) :
|
||||
self.lshwNetworkList.append(mapInfo)
|
||||
elif item.startswith("usb") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
if "description" in mapInfo and "Audio device" in mapInfo["description"] :
|
||||
self.lshwMultimediaList.append(mapInfo)
|
||||
else :
|
||||
self.lshwUsbList.append(mapInfo)
|
||||
elif item.startswith("cdrom") :
|
||||
self.getInfoFromLshw(item, mapInfo)
|
||||
self.lshwCDRomList.append(mapInfo)
|
||||
|
||||
def loadNetworkInfoFromIfconfig(self):
|
||||
args = ["ifconfig"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
items = allinfo.split("\n\n")
|
||||
for item in items :
|
||||
lines = item.strip().split("\n")
|
||||
lineCount = len(lines)
|
||||
mapInfo = {}
|
||||
for i in range(lineCount) :
|
||||
if i == 0 :
|
||||
result = re.findall("(\S+)\s+.*", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetName"] = result[0].strip().strip(":")
|
||||
result = re.findall("mtu\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMTU"] = result[0].strip()
|
||||
else :
|
||||
result = re.findall("inet\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetIp"] = result[0].strip()
|
||||
result = re.findall("netmask\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMask"] = result[0].strip()
|
||||
result = re.findall("broadcast\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetBroadcast"] = result[0].strip()
|
||||
result = re.findall("inet6\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetIp6"] = result[0].strip()
|
||||
result = re.findall("ether\s+(\S+)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetMac"] = result[0].strip()
|
||||
result = re.findall("RX packets\s+.*\((.*)\)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetRxData"] = result[0].strip()
|
||||
result = re.findall("TX packets\s+.*\((.*)\)", lines[i])
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["NetTxData"] = result[0].strip()
|
||||
|
||||
if len(mapInfo) > 0 :
|
||||
infoList.append(mapInfo)
|
||||
|
||||
return infoList
|
||||
|
||||
def loadBluetoothInfo(self, mapInfo):
|
||||
if "BD Address" not in mapInfo :
|
||||
return
|
||||
pass
|
||||
|
||||
def loadInfoFromHciconfig(self):
|
||||
args = ["hciconfig", "-a"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
items = allinfo.split("\n\n")
|
||||
for item in items :
|
||||
if len(item) == 0 :
|
||||
continue
|
||||
mapInfo = {}
|
||||
isFirstLine = True
|
||||
lines = item.strip().split("\n")
|
||||
for line in lines :
|
||||
if isFirstLine :
|
||||
result = re.findall("(hci[0-9]+):", line)
|
||||
if result and len(result) > 0 :
|
||||
mapInfo["dev_name"] = result[0]
|
||||
line = re.sub(result[0]+":","", line)
|
||||
isFirstLine = False
|
||||
linepairs = line.strip().split(" ")
|
||||
if len(linepairs) < 1 :
|
||||
continue
|
||||
for pair in linepairs :
|
||||
words = pair.strip().split(": ")
|
||||
if len(words) == 2 :
|
||||
mapInfo[words[0].strip()] = words[1].strip()
|
||||
self.loadBluetoothInfo(mapInfo)
|
||||
if len(mapInfo) > 0 :
|
||||
infoList.append(mapInfo)
|
||||
|
||||
return infoList
|
||||
|
||||
def loadGPUInfoFromDmesg(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.dmesgGPUList) > 0 :
|
||||
return None
|
||||
args = ["dmesg"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
lines = allinfo.split("\n")
|
||||
mapInfo = {}
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
result = re.findall(".*RAM width ([0-9]*bits) (.*DDR.*)", line)
|
||||
if result and len(result) > 0 :
|
||||
membitwidth = result[0][0]
|
||||
memtype = result[0][1]
|
||||
mapInfo["mem_bitwidth"] = membitwidth
|
||||
mapInfo["mem_type"] = memtype
|
||||
continue
|
||||
|
||||
result = re.findall(".*RAM=([0-9]*)M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
result = re.findall(".*RAM: ([0-9]*) M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
result = re.findall(".*RAM Size ([0-9]*)M.*", line)
|
||||
if result and len(result) > 0 and result[0].isdigit() :
|
||||
size = float(result[0])
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
mapInfo["size"] = sizeS
|
||||
continue
|
||||
if len(mapInfo) == 0 :
|
||||
mapInfo["size"] = ""
|
||||
self.dmesgGPUList.append(mapInfo)
|
||||
else :
|
||||
self.dmesgGPUList.append(mapInfo)
|
||||
return self.dmesgGPUList
|
||||
|
||||
def loadNvidiaName(self, gpuIdx) :
|
||||
if not os.path.exists("/usr/bin/nvidia-smi") :
|
||||
return None
|
||||
gpuName = None
|
||||
args = ["/usr/bin/nvidia-smi", "-L"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
gpuIndex = "GPU "+str(gpuIdx)+":(.*)"
|
||||
|
||||
value = re.findall(gpuIndex, allinfo)
|
||||
if value and len(value) > 0 :
|
||||
gpuNameLine = value[0].strip().split("(")[0]
|
||||
gpuName = gpuNameLine.strip()
|
||||
return gpuName
|
||||
|
||||
|
||||
def loadGPUInfoFromNvidiaSmi(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.nvidiaGpuList) > 0 :
|
||||
return self.nvidiaGpuList
|
||||
if not os.path.exists("/usr/bin/nvidia-smi") :
|
||||
return None
|
||||
args = ["/usr/bin/nvidia-smi", "-q", "-d", "MEMORY,CLOCK"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
gpuIdx = 0
|
||||
value = re.findall("\nGPU (.*)", allinfo)
|
||||
for gpuBusId in value :
|
||||
singleInfos = allinfo.split("\nGPU ")
|
||||
for singleInfo in singleInfos :
|
||||
if singleInfo.startswith(gpuBusId) :
|
||||
words = gpuBusId.split(":", 1)
|
||||
gpuOne = {}
|
||||
memFree = 0
|
||||
memUsed = 0
|
||||
if len(words) == 2 :
|
||||
gpuOne["nvidia_id"] = words[1]
|
||||
gpuOne["nvidia_mem"] = ""
|
||||
gpuName = self.loadNvidiaName(gpuIdx)
|
||||
if gpuName and len(gpuName) > 0 :
|
||||
gpuOne["nvidia_name"] = gpuName
|
||||
gpuIdx = gpuIdx + 1
|
||||
lines = singleInfo.split("\n")
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
words = line.strip().split(":")
|
||||
if len(words) == 1 :
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
if words[0] == "FB Memory Usage" :
|
||||
isFBSession = True
|
||||
elif words[0] == "Clocks" :
|
||||
isClockSession = True
|
||||
elif words[0] == "Max Clocks" :
|
||||
isMaxClockSession = True
|
||||
else :
|
||||
if len(words) == 2 :
|
||||
if isFBSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Total" :
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
size = float(result[0])
|
||||
if size % 128 != 0 :
|
||||
size = size + 128 - (size%128)
|
||||
sizeS = str(float("%0.1f"%(size/1024)))+"GB"
|
||||
gpuOne["nvidia_mem"] = sizeS
|
||||
else :
|
||||
gpuOne["nvidia_mem"] = valW
|
||||
elif keyW == "Used" :
|
||||
gpuOne["nvidia_mem_used"] = valW
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
memUsed = float(result[0])
|
||||
elif keyW == "Free" :
|
||||
gpuOne["nvidia_mem_free"] = valW
|
||||
result = re.findall("(.*)M.*", valW)
|
||||
if result and len(result) > 0 and result[0].isdigit():
|
||||
memFree = float(result[0])
|
||||
elif isClockSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Graphics" :
|
||||
if "N/A" not in valW and len(valW) > 0 :
|
||||
gpuOne["nvidia_clock"] = valW
|
||||
elif isMaxClockSession :
|
||||
keyW = words[0].strip()
|
||||
valW = words[1].strip().replace(" ", "")
|
||||
if keyW == "Graphics" :
|
||||
if "N/A" not in valW and len(valW) > 0 :
|
||||
gpuOne["nvidia_maxclock"] = valW
|
||||
else :
|
||||
isFBSession = False
|
||||
isClockSession = False
|
||||
isMaxClockSession = False
|
||||
if len(gpuOne) > 0 :
|
||||
if memFree != 0 or memUsed != 0 :
|
||||
gpuOne["nvidia_mem_percent"] = float("%0.1f"%((memUsed/(memFree+memUsed))*100))
|
||||
infoList.append(gpuOne)
|
||||
self.nvidiaGpuList = infoList
|
||||
return infoList
|
||||
|
||||
def loadSoundInfoFromPacmd(self, forceUpdate = True) :
|
||||
if not forceUpdate and len(self.pacmdSoundList) > 0 :
|
||||
return self.pacmdSoundList
|
||||
if not os.path.exists("/usr/bin/pacmd") :
|
||||
return None
|
||||
|
||||
args = ["/usr/bin/pacmd", "list-cards"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infoList = []
|
||||
value = re.findall("index: (.*)", allinfo)
|
||||
for cardId in value :
|
||||
singleInfos = allinfo.split("index: ")
|
||||
for singleInfo in singleInfos :
|
||||
if singleInfo.startswith(cardId) :
|
||||
soundCardOne = {}
|
||||
lines = singleInfo.split("\n")
|
||||
isPropSession = False
|
||||
for line in lines :
|
||||
if len(line) == 0 :
|
||||
continue
|
||||
if not isPropSession :
|
||||
words = line.strip().split(":")
|
||||
if words[0] == "properties" :
|
||||
isPropSession = True
|
||||
else :
|
||||
if isPropSession :
|
||||
propWords = line.strip().split("=")
|
||||
if len(propWords) == 2 :
|
||||
keyPropW = propWords[0].strip()
|
||||
valPropW = propWords[1].strip().replace("\"", "")
|
||||
if keyPropW == "alsa.card_name" : #名称
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_name"] = valPropW
|
||||
elif keyPropW == "alsa.long_card_name" : #型号
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_model"] = valPropW
|
||||
elif keyPropW == "device.vendor.name" : #厂商
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_vendor"] = valPropW
|
||||
elif keyPropW == "alsa.driver_name" : #驱动
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_driver"] = valPropW
|
||||
elif keyPropW == "device.icon_name" : #?
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_icon"] = valPropW
|
||||
elif keyPropW == "device.bus_path" : #总线地址
|
||||
if len(valPropW) > 0 :
|
||||
soundCardOne["sound_busaddr"] = valPropW
|
||||
if "sound_icon" in soundCardOne and "sound_driver" not in soundCardOne :
|
||||
soundCardOne["sound_driver"] = soundCardOne["sound_icon"]
|
||||
if len(soundCardOne) > 0 :
|
||||
infoList.append(soundCardOne)
|
||||
self.pacmdSoundList = infoList
|
||||
return infoList
|
||||
|
||||
def getUsbVendorProduct(self, vendorid, productid) :
|
||||
if len(vendorid) == 0 or len(productid) == 0 :
|
||||
return "",""
|
||||
|
||||
args = ["lsusb"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
vendor,product = "",""
|
||||
allinfo = ""
|
||||
for l in output:
|
||||
allinfo += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
infolines = allinfo.split("\n")
|
||||
vendorinfo = vendorid+":"+productid
|
||||
businfo = ""
|
||||
for infoline in infolines :
|
||||
if vendorinfo in infoline :
|
||||
result = re.findall("Bus ([0-9]*) Device ([0-9]*)", infoline)
|
||||
if result and len(result) > 0 :
|
||||
businfo = result[0][0]+":"+result[0][1]
|
||||
break;
|
||||
if len(businfo) > 0 :
|
||||
args1 = ["lsusb", "-vs", businfo]
|
||||
pipe1 = subprocess.Popen(args1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output1 = pipe1.stdout.readlines()
|
||||
|
||||
allinfo1 = ""
|
||||
for l in output1:
|
||||
allinfo1 += bytes.decode(l,"utf-8","ignore")
|
||||
|
||||
retVendor = re.findall("idVendor[\s]+0x[0-9]+[\s]+(.*)", allinfo1)
|
||||
if retVendor and len(retVendor) > 0 :
|
||||
vendor = retVendor[0]
|
||||
retProduct = re.findall("idProduct[\s]+0x[0-9]+[\s]+(.*)", allinfo1)
|
||||
if retProduct and len(retProduct) > 0 :
|
||||
product = retProduct[0]
|
||||
|
||||
return vendor,product
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KACmdTool()
|
||||
#cc.loadInfoFromLshw()
|
||||
# pprint(cc.lshwSystemList)
|
||||
# pprint(cc.lshwCpuList)
|
||||
# pprint(cc.lshwStorageList)
|
||||
# pprint(cc.lshwMemoryList)
|
||||
# pprint(cc.lshwDisplayList)
|
||||
# pprint(cc.lshwMultimediaList)
|
||||
# pprint(cc.lshwNetworkList)
|
||||
# pprint(cc.lshwUsbList)
|
||||
# pprint(cc.lshwCDRomList)
|
||||
# pprint(cc.loadNetworkInfoFromIfconfig())
|
||||
# pprint(cc.loadInfoFromHciconfig())
|
||||
pprint(cc.loadGPUInfoFromNvidiaSmi())
|
||||
# pprint(cc.loadSoundInfoFromPacmd())
|
||||
# pprint(cc.getUsbVendorProduct("0951","1666"))
|
||||
|
||||
# diskList = cc.loadInfoFromHwinfo("--disk")
|
||||
# cc.loadDiskInfoFromLsblk()
|
||||
# if "list" in diskList and len(diskList["list"]) > 0 :
|
||||
# length = len(diskList["list"])
|
||||
# for i in range(length) :
|
||||
# if "SysFS BusID" in diskList["list"][i] :
|
||||
# for mapInfo in cc.lshwDiskList :
|
||||
# if "bus info" in mapInfo :
|
||||
# words = mapInfo["bus info"].split("@")
|
||||
# if len(words) != 2 :
|
||||
# continue
|
||||
# key = words[1].strip()
|
||||
# key = key.replace(".",":")
|
||||
# if key != diskList["list"][i]["SysFS BusID"] :
|
||||
# continue
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# if "SysFS Device Link" in diskList["list"][i]:
|
||||
# for mapInfo in cc.lshwStorageList :
|
||||
# if "bus info" in mapInfo :
|
||||
# words = mapInfo["bus info"].split("@")
|
||||
# if len(words) != 2 :
|
||||
# continue
|
||||
# key = words[1].strip().lower()
|
||||
# if key not in diskList["list"][i]["SysFS Device Link"].lower() :
|
||||
# continue
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# for mapInfo in cc.lsblkSmartList :
|
||||
# if "dev_name" in mapInfo and "Device File" in diskList["list"][i] \
|
||||
# and mapInfo["dev_name"] in diskList["list"][i]["Device File"] :
|
||||
# diskList["list"][i].update(mapInfo)
|
||||
# pprint(diskList)
|
|
@ -0,0 +1,214 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from subprocess import PIPE
|
||||
import threading
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
from gi.repository import GLib
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kapolicykit import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
OBJPATH_CPUFM = '/com/kylin/assistant/cpufm'
|
||||
INTERFACE_CPUFM = 'com.kylin.assistant.systemdaemon'
|
||||
|
||||
class KACpuFM(dbus.service.Object):
|
||||
def __init__(self, system_bus, mainloop):
|
||||
# Init dbus service.
|
||||
dbus.service.Object.__init__(self, system_bus, OBJPATH_CPUFM)
|
||||
|
||||
self.mainloop = mainloop
|
||||
|
||||
self.policykitservice = PolicyKitService()
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='', sender_keyword='sender')
|
||||
def exit(self, sender = None):
|
||||
self.mainloop.quit()
|
||||
|
||||
@dbus.service.signal(INTERFACE_CPUFM, signature='us')
|
||||
def signalUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def getCpuFMInfo(self, sender=None):
|
||||
asyncObj = KAThread(self.readCpuFMInfo, self.signalUpdateInfo, args=())
|
||||
asyncObj.start()
|
||||
self.signalUpdateInfo(0, asyncObj.getResult())
|
||||
return str(asyncObj.getResult())
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='as', sender_keyword='sender')
|
||||
def get_cpufreq_scaling_governer_list(self, sender=None):
|
||||
cpulist = []
|
||||
if not os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors") :
|
||||
return cpulist
|
||||
cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read().strip('\n')
|
||||
fp.close()
|
||||
if msg not in ['', None]:
|
||||
cpulist = msg.split(' ')
|
||||
|
||||
if not os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"):
|
||||
if 'userspace' in cpulist:
|
||||
cpulist.remove('userspace')
|
||||
else:
|
||||
cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read().strip('\n')
|
||||
fp.close()
|
||||
if msg not in ['',None]:
|
||||
if msg == '<unsupported>' and 'userspace' in cpulist:
|
||||
cpulist.remove('userspace')
|
||||
|
||||
if Judgment_HW990() and ('userspace' in cpulist):
|
||||
cpulist.remove('userspace')
|
||||
return cpulist
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readCpuFMInfo(self, sender=None):
|
||||
cpuFMInfo = {Cpufm_Root:{}}
|
||||
cpuFMInfo[Cpufm_Root][Cpufm_Models] = self.get_cpufreq_scaling_governer_list()
|
||||
cpuFMInfo[Cpufm_Root][Cpufm_Freqs] = self.get_cpufreq_scaling_available_frequencies()
|
||||
cpuFMInfo[Cpufm_Root][Cpufm_Current_Model] = self.get_current_cpufreq_scaling_governer()
|
||||
cpuFMInfo[Cpufm_Root].update(self.get_cpu_average_frequency())
|
||||
strJson = json.dumps(cpuFMInfo)
|
||||
return strJson
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='as', sender_keyword='sender')
|
||||
def get_cpufreq_scaling_available_frequencies(self, sender=None):
|
||||
cpulist = []
|
||||
if not os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies") :
|
||||
return cpulist
|
||||
cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies"
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read().strip()
|
||||
fp.close()
|
||||
if msg not in ['', None]:
|
||||
cpulist = msg.split(' ')
|
||||
|
||||
return cpulist
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def get_current_cpufreq_scaling_governer(self, sender=None):
|
||||
if not os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor") :
|
||||
return ""
|
||||
cmd = "cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read().strip('\n')
|
||||
fp.close()
|
||||
return msg
|
||||
|
||||
# cpu频率的单位换算
|
||||
def num_convert(self,s):
|
||||
if not s.isdigit() :
|
||||
return "0Ghz"
|
||||
num = int(s)
|
||||
unit=""
|
||||
for i in range(0,10):
|
||||
if( i == 1 ):
|
||||
unit = "Mhz"
|
||||
elif ( i == 2):
|
||||
unit = "Ghz"
|
||||
|
||||
if(num >= 10):
|
||||
num=round(num/1000,1)
|
||||
else:
|
||||
break
|
||||
|
||||
return str(num)+unit
|
||||
|
||||
def get_cpu_average_frequency(self):
|
||||
origin = {Cpufm_Average_Corefreq:""}
|
||||
|
||||
if(not os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq")):
|
||||
return origin
|
||||
|
||||
v = 0
|
||||
i = 0
|
||||
fpath = os.path.expanduser("/sys/devices/system/cpu/")
|
||||
for line in os.listdir(fpath): #遍历/sys/devices/system/cpu/下的所有文件
|
||||
line = line.strip('\n')
|
||||
#pattern = re.compile(r'cpu.*[0-9]$')
|
||||
pattern = re.compile(r'cpu.*\d\Z') #筛选cpu的每个核心的配置文件
|
||||
m = pattern.match(line)
|
||||
if m:
|
||||
filepath = "/sys/devices/system/cpu/%s/cpufreq/scaling_cur_freq" % line
|
||||
if os.path.exists(filepath):
|
||||
f = open(filepath,'r')
|
||||
curFreq = f.readline().strip()
|
||||
if curFreq.isdigit() :
|
||||
v += int(curFreq)
|
||||
i = i + 1
|
||||
|
||||
v = self.num_convert(str(v//i))
|
||||
origin[Cpufm_Average_Corefreq]=v
|
||||
|
||||
return origin
|
||||
|
||||
@dbus.service.method(INTERFACE_CPUFM, in_signature='s', out_signature='s', sender_keyword='sender')
|
||||
def adjust_cpufreq_scaling_governer(self, value, sender=None):
|
||||
cpuFMSetting = json.loads(value)
|
||||
validFreqList = self.get_cpufreq_scaling_available_frequencies()
|
||||
validFMList = self.get_cpufreq_scaling_governer_list()
|
||||
cpuFMModel = ""
|
||||
cpuFMFreq = ""
|
||||
if cpuFMSetting != None :
|
||||
cpuFMModel = cpuFMSetting[Cpufm_Current_Model]
|
||||
cpuFMFreq = cpuFMSetting[Cpufm_CurFreq]
|
||||
if not validFMList or cpuFMModel not in validFMList or \
|
||||
(cpuFMModel == Cpufm_Model_Userspace and (not validFreqList or (cpuFMFreq not in validFreqList))) :
|
||||
return "Failed,param mismatch!"
|
||||
fpath = os.path.expanduser("/sys/devices/system/cpu/")
|
||||
for line in os.listdir(fpath):
|
||||
line = line.strip('\n')
|
||||
#pattern = re.compile(r'cpu.*[0-9]$')
|
||||
pattern = re.compile(r'cpu.*\d\Z')
|
||||
m = pattern.match(line)
|
||||
if m:
|
||||
filepath = "/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % line
|
||||
path = "/sys/devices/system/cpu/%s/cpufreq/scaling_setspeed" % line
|
||||
if os.path.exists(filepath):
|
||||
if(cpuFMModel == Cpufm_Model_Userspace):
|
||||
cmd = 'echo %s > %s' % (cpuFMModel, filepath)
|
||||
os.system(cmd)
|
||||
cmd = 'echo %s > %s' % (cpuFMFreq, path)
|
||||
os.system(cmd)
|
||||
else:
|
||||
cmd = 'echo %s > %s' % (cpuFMModel, filepath)
|
||||
os.system(cmd)
|
||||
return "Success!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
|
@ -0,0 +1,187 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from subprocess import PIPE
|
||||
import threading
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
from gi.repository import GLib
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kapolicykit import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
OBJPATH_DEVMONITOR = '/com/kylin/assistant/devmonitor'
|
||||
INTERFACE_DEVMONITOR = 'com.kylin.assistant.systemdaemon'
|
||||
CPUSTAT_FILE = "/proc/stat"
|
||||
|
||||
class KADevMonitor(dbus.service.Object):
|
||||
def __init__(self, system_bus, mainloop):
|
||||
# Init dbus service.
|
||||
dbus.service.Object.__init__(self, system_bus, OBJPATH_DEVMONITOR)
|
||||
|
||||
self.mainloop = mainloop
|
||||
|
||||
self.policykitservice = PolicyKitService()
|
||||
|
||||
self.preTotalTime = 0
|
||||
self.preWorkTime = 0
|
||||
self.totalTime = 0
|
||||
self.workTime = 0
|
||||
self.cpuPercent = 0
|
||||
self.cpuTimer = threading.Timer(0.3, self.chkCpuUsageTimer)
|
||||
self.cpuTimer.start()
|
||||
|
||||
@dbus.service.method(INTERFACE_DEVMONITOR, in_signature='', out_signature='', sender_keyword='sender')
|
||||
def exit(self, sender = None):
|
||||
self.mainloop.quit()
|
||||
|
||||
@dbus.service.signal(INTERFACE_DEVMONITOR, signature='us')
|
||||
def signalUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE_DEVMONITOR, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def getDevMonitorInfo(self, sender=None):
|
||||
asyncObj = KAThread(self.readDevMonitorInfo, self.signalUpdateInfo, args=())
|
||||
asyncObj.start()
|
||||
self.signalUpdateInfo(0, asyncObj.getResult())
|
||||
return str(asyncObj.getResult())
|
||||
|
||||
@dbus.service.method(INTERFACE_DEVMONITOR, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def getDevTempsInfo(self, sender=None):
|
||||
return ""
|
||||
|
||||
@dbus.service.method(INTERFACE_DEVMONITOR, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readDevMonitorInfo(self, sender=None):
|
||||
devMonitorInfo = {DEVMONITOR_ROOT:{}}
|
||||
devTempsInfo = []
|
||||
devTempsInfo.append(self.getCpuTemps())
|
||||
devMonitorInfo[DEVMONITOR_ROOT][DEVMONITOR_DEVTEMPS] = devTempsInfo
|
||||
devUsageInfo = []
|
||||
devUsageInfo.append(self.readCpuUsage())
|
||||
devUsageInfo.append(self.readMemUsage())
|
||||
devMonitorInfo[DEVMONITOR_ROOT][DEVMONITOR_DEVUSAGE] = devUsageInfo
|
||||
strJson = json.dumps(devMonitorInfo)
|
||||
return strJson
|
||||
|
||||
def chkCpuUsageTimer(self):
|
||||
cmd = "cat " + CPUSTAT_FILE
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read()
|
||||
fp.close()
|
||||
result = re.findall('cpu\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)', msg);
|
||||
self.preTotalTime = self.totalTime
|
||||
self.preWorkTime = self.workTime
|
||||
if result :
|
||||
user = int(result[0][0])
|
||||
nice = int(result[0][1])
|
||||
system = int(result[0][2])
|
||||
idle = int(result[0][3])
|
||||
iowait = int(result[0][4])
|
||||
irq = int(result[0][5])
|
||||
softirq = int(result[0][6])
|
||||
steal = int(result[0][7])
|
||||
guest = int(result[0][8])
|
||||
guestnice = int(result[0][9])
|
||||
self.workTime = user + nice + system
|
||||
self.totalTime = user + nice + system + idle + iowait + irq + softirq + steal
|
||||
if self.preTotalTime != 0 and self.preWorkTime != 0 :
|
||||
self.cpuPercent = int(((self.workTime - self.preWorkTime) * 1000 / (self.totalTime - self.preTotalTime)))/10
|
||||
else :
|
||||
self.cpuPercent = 0
|
||||
## next timer
|
||||
self.cpuTimer = threading.Timer(1, self.chkCpuUsageTimer)
|
||||
self.cpuTimer.start()
|
||||
|
||||
def readCpuUsage(self):
|
||||
cpuUsage = {}
|
||||
cpuUsage[DEVMONITOR_DEVUSAGE_NAME] = "CPU"
|
||||
cpuUsage[DEVMONITOR_DEVUSAGE_USED] = str(self.cpuPercent)
|
||||
cpuUsage[DEVMONITOR_DEVUSAGE_TOTAL] = str(100)
|
||||
return cpuUsage
|
||||
|
||||
def readMemUsage(self):
|
||||
cmd = "free"
|
||||
fp = os.popen(cmd)
|
||||
msg = fp.read()
|
||||
fp.close()
|
||||
memUsedByte = 0
|
||||
memTotalByte = 0
|
||||
memLeftByte = 0
|
||||
memUsedPercent = 0
|
||||
msgLines = msg.split("\n")
|
||||
if msgLines :
|
||||
for line in msgLines :
|
||||
infoArray = re.split("\s+",line)
|
||||
if infoArray and len(infoArray) >= 7 and infoArray[1].isdigit() and infoArray[6].isdigit() : #is mem info
|
||||
memLeftByte = int(infoArray[6])
|
||||
memTotalByte = int(infoArray[1])
|
||||
memUsedByte = memTotalByte - memLeftByte
|
||||
if memTotalByte != 0 :
|
||||
memUsedPercent = int(memUsedByte*1000/memTotalByte)/10
|
||||
else :
|
||||
memUsedPercent = 0
|
||||
memUsage = {}
|
||||
memUsage[DEVMONITOR_DEVUSAGE_NAME] = "MEM"
|
||||
memUsage[DEVMONITOR_DEVUSAGE_USED] = str(memUsedPercent)
|
||||
memUsage[DEVMONITOR_DEVUSAGE_TOTAL] = str(100)
|
||||
return memUsage
|
||||
|
||||
def getCpuTemps(self):
|
||||
sensorTemps = []
|
||||
sensorTempAvg = 0
|
||||
sensorTempHigh = 0
|
||||
sensorTempCrit = 0
|
||||
cpuTemps = {}
|
||||
status, output = subprocess.getstatusoutput("sensors")
|
||||
if(status != -1):
|
||||
#Core 0: +35.0°C (high = +84.0°C, crit = +100.0°C)
|
||||
result = re.findall('Core\s*[0-9]+:\s*(\S+)°C\s*\(high\s*=\s*(\S+)°C,\s*crit\s*=\s*(\S+)°C\)', output)
|
||||
#print(result)
|
||||
if result :
|
||||
for line in result:
|
||||
oneCoreTemp = float(line[0])
|
||||
sensorTempHigh = float(line[1])
|
||||
sensorTempCrit = float(line[2])
|
||||
sensorTemps.append(oneCoreTemp)
|
||||
sensorTempAvg += oneCoreTemp
|
||||
if len(sensorTemps) > 0 :
|
||||
sensorTempAvg = int(sensorTempAvg*10/len(sensorTemps))/10
|
||||
cpuTemps[DEVMONITOR_DEVTEMP] = str(sensorTempAvg)
|
||||
cpuTemps[DEVMONITOR_DEVTEMP_HIGH] = str(sensorTempHigh)
|
||||
cpuTemps[DEVMONITOR_DEVTEMP_CRIT] = str(sensorTempCrit)
|
||||
cpuTemps[DEVMONITOR_DEVTEMP_NAME] = "CPU"
|
||||
return cpuTemps
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from smbus import SMBus
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
|
||||
class KAFanInfo():
|
||||
|
||||
def __init__(self):
|
||||
try:
|
||||
self.i2cbus = SMBus(2)
|
||||
except IOError:
|
||||
self.i2cbus = None
|
||||
pass
|
||||
|
||||
def getFanInfo(self):
|
||||
summary = {"list":[]}
|
||||
origin = {}
|
||||
mid = {}
|
||||
|
||||
status, output = subprocess.getstatusoutput("sensors")
|
||||
|
||||
if (status != -1):
|
||||
for line in output.split("\n"):
|
||||
lineInfo = line.split(":")
|
||||
if len(lineInfo) >= 2 and lineInfo[0].lstrip().startswith("fan") :
|
||||
origin[lineInfo[0].strip()]=lineInfo[1].strip().split(" ")[0]
|
||||
|
||||
if (not bool(origin) or "fan1" not in origin or not origin["fan1"].isdigit() or not int(origin["fan1"])):
|
||||
try:
|
||||
data1 = self.i2cbus.read_byte_data(0x3c, 0x30)
|
||||
data2 = self.i2cbus.read_byte_data(0x3c, 0x31)
|
||||
result = (int(hex(data1), 16) << 8) | int(hex(data2), 16)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
mid['fan1'] = result
|
||||
origin.update(mid)
|
||||
for key in origin:
|
||||
info = {}
|
||||
info[FAI_NAME] = key
|
||||
info[FAI_SPEED] = origin[key]
|
||||
summary["list"].append(info)
|
||||
return json.dumps(summary)
|
||||
|
||||
def getCpuFanEnable(self) :
|
||||
show = False
|
||||
status, output = subprocess.getstatusoutput("sensors")
|
||||
if ( status == 0 ):
|
||||
for line in output.split("\n"):
|
||||
lineInfo = line.split(":")
|
||||
if len(lineInfo) >= 2 and lineInfo[0].lstrip().startswith("fan") :
|
||||
fanSpeed = lineInfo[1].strip().split(" ")[0]
|
||||
if (fanSpeed.isdigit() and int(fanSpeed)>0):
|
||||
show = True
|
||||
else:
|
||||
show = False
|
||||
|
||||
if ( not show ):
|
||||
try:
|
||||
b = SMBus(2)
|
||||
data1 = b.read_byte_data(0x3c, 0x30)
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
if data1 != 0:
|
||||
show = True
|
||||
|
||||
return show
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KAFanInfo()
|
||||
pprint(cc.getFanInfo())
|
||||
#pprint(cc.getOutline())
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import math
|
||||
import glob
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
subsystem_id = "LANG=en lspci -d 0731:7200 -v | sed -n '/Subsystem:/p' | awk -F: '{ print $NF }'"
|
||||
subsystem_id_old = "lspci -d 0731:7200 | awk -F: '{ print $NF }'" #兼容旧驱动
|
||||
subsystem_id_re = re.compile(r'Subsystem:(.*?\d{3,5})')
|
||||
subsystem_id_re_old = re.compile(r'.*')
|
||||
|
||||
def get_interface(com, pci_str):
|
||||
"输入想要的命令,并获取想要内容的函数,第一个参数是命令,第二个参数是正则表达式"
|
||||
res = subprocess.Popen(com, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=10)
|
||||
inter1 = res.stdout.read()
|
||||
inter = inter1.decode('utf-8')
|
||||
result = inter
|
||||
return result
|
||||
|
||||
class KAGraphicsCardInfo() :
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def get_display_hw990(self):
|
||||
displayInfo = {}
|
||||
wayland_sock = glob.glob('/run/user/*/wayland-0')[0]
|
||||
xdg_runtime_dir = wayland_sock[:-10] # /run/user/1000
|
||||
gpuinfo_env = {'XDG_RUNTIME_DIR' : xdg_runtime_dir}
|
||||
process = subprocess.run('gpuinfo', env=gpuinfo_env, capture_output=True)
|
||||
output = process.stdout.decode()
|
||||
ret = process.returncode
|
||||
if ret == 1: ## ???
|
||||
lines = output.strip().split('\n')
|
||||
for line in lines:
|
||||
if line.find(':') > 0:
|
||||
if line.find('GPU vendor') >= 0: # GPU vendor: ARM
|
||||
displayInfo[GSI_MANUFACTURER] = line.split(':')[1].strip()
|
||||
elif line.find('GPU type') >= 0: # GPU type: Mali-G76
|
||||
displayInfo[GSI_NAME] = line.split(':')[1].strip()
|
||||
elif "GDDR capacity" in line:
|
||||
displayInfo[GSI_GDDRCAPACITY] = line.split(':')[1].strip()
|
||||
elif "EGL version" in line:
|
||||
displayInfo[GSI_EGLVERSION] = line.split(':')[1].strip()
|
||||
elif "EGL client APIs" in line:
|
||||
displayInfo[GSI_EGLAPIS] = line.split(':')[1].strip()
|
||||
elif "GL version" in line:
|
||||
displayInfo[GSI_GLVERSION] = line.split(':')[1].strip()
|
||||
elif "GLSL version" in line:
|
||||
displayInfo[GSI_GLSLVERSION] = line.split(':')[1].strip()
|
||||
else:
|
||||
pass
|
||||
else: # integrated graphics controller
|
||||
displayInfo[GSI_DESC] = line
|
||||
return displayInfo
|
||||
|
||||
def getGraphicsCardInfo(self) :
|
||||
summary = {"list":[]}
|
||||
|
||||
self.cmdTool.loadGPUInfoFromDmesg(False)
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
self.cmdTool.loadGPUInfoFromNvidiaSmi(False)
|
||||
graphicsCardList = self.cmdTool.lshwDisplayList
|
||||
cardList = self.cmdTool.loadInfoFromHwinfo("--display")["list"]
|
||||
length = len(graphicsCardList)
|
||||
for i in range(length) :
|
||||
if "bus info" in graphicsCardList[i] :
|
||||
words = graphicsCardList[i]["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip()
|
||||
#key = key.replace(".","" in mapInfo
|
||||
for mapInfo in cardList :
|
||||
if "SysFS BusID" in mapInfo :
|
||||
if key != mapInfo["SysFS BusID"] :
|
||||
continue
|
||||
graphicsCardList[i].update(mapInfo)
|
||||
result = key.split(":", 1)
|
||||
if result and len(result) == 2 :
|
||||
key = result[1]
|
||||
for mapInfo in self.cmdTool.nvidiaGpuList :
|
||||
if "nvidia_id" in mapInfo :
|
||||
if key != mapInfo["nvidia_id"] :
|
||||
continue
|
||||
graphicsCardList[i].update(mapInfo)
|
||||
if len(self.cmdTool.dmesgGPUList) > 0 :
|
||||
graphicsCardList[i].update(self.cmdTool.dmesgGPUList[0])
|
||||
|
||||
index = 0
|
||||
for mapInfo in graphicsCardList :
|
||||
if len(mapInfo) > 0 :
|
||||
pciAddr = ""
|
||||
summary["list"].append({})
|
||||
isJJM = False
|
||||
##名称
|
||||
if "product" in mapInfo :
|
||||
summary["list"][index][GSI_NAME] = mapInfo["product"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
cdVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(cdVendor) > 1 :
|
||||
summary["list"][index][GSI_MANUFACTURER] = cdVendor[1]
|
||||
else :
|
||||
summary["list"][index][GSI_MANUFACTURER] = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
cdVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(cdVendor) > 1 :
|
||||
summary["list"][index][GSI_MANUFACTURER] = cdVendor[1]
|
||||
else :
|
||||
summary["list"][index][GSI_MANUFACTURER] = mapInfo["SubVendor"]
|
||||
if "vendor" in mapInfo :
|
||||
summary["list"][index][GSI_MANUFACTURER] = mapInfo["vendor"]
|
||||
|
||||
# JJW显卡的特殊处理
|
||||
tmpVendor = mapInfo["vendor"]
|
||||
if tmpVendor.find("JJM") != -1:
|
||||
isJJM = True
|
||||
tmpResult = get_interface(subsystem_id, subsystem_id_re)
|
||||
summary["list"][index][GSI_NAME] = tmpResult.strip()
|
||||
if not tmpResult:
|
||||
summary["list"][index][GSI_NAME] = get_interface(subsystem_id_old, subsystem_id_re_old).strip()
|
||||
|
||||
|
||||
##类型
|
||||
if "description" in mapInfo :
|
||||
summary["list"][index][GSI_DESC] = mapInfo["description"]
|
||||
|
||||
##版本
|
||||
if "version" in mapInfo :
|
||||
summary["list"][index][GSI_VERSION] = mapInfo["version"]
|
||||
|
||||
##总线信息
|
||||
if "bus info" in mapInfo :
|
||||
summary["list"][index][GSI_DBUSINFO] = mapInfo["bus info"]
|
||||
pciResult = re.findall("pci@(\S+)", mapInfo["bus info"])
|
||||
if pciResult :
|
||||
pciAddr = pciResult[0]
|
||||
|
||||
##功能
|
||||
if "capabilities" in mapInfo :
|
||||
summary["list"][index][GSI_FUNCTION] = mapInfo["capabilities"]
|
||||
|
||||
##位宽 (不准确,暂时不显示)
|
||||
# if "width" in mapInfo :
|
||||
# summary["list"][index][GSI_BITWIDTH] = mapInfo["width"]
|
||||
|
||||
##物理ID
|
||||
if "physical id" in mapInfo :
|
||||
summary["list"][index][GSI_PHYSICS] = mapInfo["physical id"]
|
||||
|
||||
##时钟频率
|
||||
if "clock" in mapInfo :
|
||||
summary["list"][index][GSI_CLOCK] = mapInfo["clock"]
|
||||
##NVIDIA显卡
|
||||
if "nvidia_maxclock" in mapInfo :
|
||||
summary["list"][index][GSI_CLOCK] = mapInfo["nvidia_maxclock"]
|
||||
|
||||
##中断
|
||||
if "irq" in mapInfo :
|
||||
summary["list"][index][GSI_IRQ] = mapInfo["irq"]
|
||||
|
||||
##内存
|
||||
#if "memory" in mapInfo :
|
||||
# summary["list"][index][GSI_MEMORY] = mapInfo["memory"]
|
||||
|
||||
##io端口
|
||||
if "ioport" in mapInfo :
|
||||
summary["list"][index][GSI_IOPORT] = mapInfo["ioport"]
|
||||
|
||||
# ##驱动
|
||||
# if "driver" in mapInfo :
|
||||
# summary["list"][index][GSI_DRIVER] = mapInfo["driver"]
|
||||
|
||||
##延迟
|
||||
if "latency" in mapInfo :
|
||||
summary["list"][index][GSI_DELAY] = mapInfo["latency"]
|
||||
|
||||
##显存
|
||||
if isJJM and os.path.exists("/proc/gpuinfo_0"):
|
||||
args4 = ["cat", "/proc/gpuinfo_0"]
|
||||
pipe4 = subprocess.Popen(args4, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output4 = pipe4.stdout.readlines()
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output4]:
|
||||
if "Memory Size" not in line:
|
||||
continue
|
||||
|
||||
results = line.strip().split(":")
|
||||
if len(results) == 2 :
|
||||
temSize = results[1].strip()
|
||||
summary["list"][index][GSI_CAPCITY] = temSize.replace(" ","")
|
||||
|
||||
if (GSI_NAME in summary["list"][index] and "X100" in summary["list"][index][GSI_NAME]) or \
|
||||
(GSI_MANUFACTURER in summary["list"][index] and "X100" in summary["list"][index][GSI_MANUFACTURER]): ## X100
|
||||
args3 = ["lspci", "-n"]
|
||||
pipe3 = subprocess.Popen(args3, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output3 = pipe3.stdout.readlines()
|
||||
totalMem = 0
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output3]:
|
||||
if "1db7:dc20" not in line and "1db7:dc21" not in line and "1db7:dc22" not in line :
|
||||
continue
|
||||
infoItems = line.split(" ")
|
||||
if len(infoItems) != 3 :
|
||||
continue
|
||||
args4 = ["lspci", "-vs"]
|
||||
args4.append(infoItems[0].strip())
|
||||
pipe4 = subprocess.Popen(args4, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output4 = pipe4.stdout.readlines()
|
||||
singleMem = 0
|
||||
for line1 in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output4]:
|
||||
if "Memory" not in line1:
|
||||
continue
|
||||
|
||||
results = [ v.strip().strip("\)") for v in line1.split() ]
|
||||
if "prefetchable" in results :
|
||||
## Memory at a0000000 (64-bit, prefetchable) [size=256M]
|
||||
for session in results :
|
||||
if "size" not in session :
|
||||
continue
|
||||
strMem = session.strip("[").strip("]").split("=")
|
||||
if len(strMem) == 2 :
|
||||
sizeN = re.findall("([0-9]+)M.*",strMem[1])
|
||||
if sizeN and len(sizeN) > 0 and sizeN[0].isdigit() :
|
||||
if int(sizeN[0]) > singleMem :
|
||||
singleMem = int(sizeN[0])
|
||||
sizeN = re.findall("([0-9]+)G.*",strMem[1])
|
||||
if sizeN and len(sizeN) > 0 and sizeN[0].isdigit() :
|
||||
if int(sizeN[0])*1024 > singleMem :
|
||||
singleMem = int(sizeN[0])*1024
|
||||
totalMem += singleMem
|
||||
if totalMem > 0 :
|
||||
if totalMem > 1024 :
|
||||
summary["list"][index][GSI_CAPCITY] = str(float("%0.1f"%(float(totalMem)/1024)))+"GB"
|
||||
else :
|
||||
summary["list"][index][GSI_CAPCITY] = str(totalMem)+"MB"
|
||||
|
||||
if GSI_CAPCITY not in summary["list"][index] :
|
||||
if "size" in mapInfo and len(mapInfo["size"]) > 0:
|
||||
summary["list"][index][GSI_CAPCITY] = mapInfo["size"]
|
||||
else :
|
||||
if len(pciAddr) > 0 :
|
||||
args3 = ["lspci", "-vs"]
|
||||
args3.append(pciAddr)
|
||||
pipe3 = subprocess.Popen(args3, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output3 = pipe3.stdout.readlines()
|
||||
totalMem = 0
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output3]:
|
||||
if "Memory" not in line:
|
||||
continue
|
||||
|
||||
results = [ v.strip().strip("\)") for v in line.split() ]
|
||||
if "prefetchable" in results and len(results) >=6 :
|
||||
## Memory at a0000000 (64-bit, prefetchable) [size=256M]
|
||||
strMem = results[5].strip("[").strip("]").split("=")
|
||||
if len(strMem) == 2 :
|
||||
sizeN = re.findall("([0-9]+)M.*",strMem[1])
|
||||
if sizeN and len(sizeN) > 0 and sizeN[0].isdigit() :
|
||||
if int(sizeN[0]) > totalMem :
|
||||
totalMem = int(sizeN[0])
|
||||
sizeN = re.findall("([0-9]+)G.*",strMem[1])
|
||||
if sizeN and len(sizeN) > 0 and sizeN[0].isdigit() :
|
||||
if int(sizeN[0])*1024 > totalMem :
|
||||
totalMem = int(sizeN[0])*1024
|
||||
|
||||
if totalMem > 0 :
|
||||
if totalMem > 1024 :
|
||||
summary["list"][index][GSI_CAPCITY] = str(float("%0.1f"%(float(totalMem)/1024)))+"GB"
|
||||
else :
|
||||
summary["list"][index][GSI_CAPCITY] = str(totalMem)+"MB"
|
||||
if "nvidia_mem" in mapInfo and len(mapInfo["nvidia_mem"]) > 0 :
|
||||
summary["list"][index][GSI_CAPCITY] = mapInfo["nvidia_mem"]
|
||||
|
||||
#显存类型
|
||||
if GSI_CAPCITY in summary["list"][index] and "mem_type" in mapInfo and len(mapInfo["mem_type"]) > 0 :
|
||||
summary["list"][index][GSI_MEMTYPE] = mapInfo["mem_type"]
|
||||
|
||||
#子制造商
|
||||
if len(pciAddr) > 0 :
|
||||
args3 = ["lspci", "-vvs"]
|
||||
args3.append(pciAddr)
|
||||
pipe3 = subprocess.Popen(args3, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output3 = pipe3.stdout.readlines()
|
||||
subSystemInfo = ""
|
||||
pciStatusClock = ""
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output3]:
|
||||
words = line.split(":")
|
||||
if len(words) == 2 :
|
||||
keyWord = words[0].strip()
|
||||
valWord = words[1].strip()
|
||||
if keyWord == "Subsystem" :
|
||||
subSystemInfo = valWord
|
||||
elif keyWord == "Status" :
|
||||
result = re.findall("[\s]*([0-9]+MHz)-.*", valWord)
|
||||
if result and len(result) > 0 :
|
||||
pciStatusClock = result[0]
|
||||
if len(subSystemInfo) > 0 :
|
||||
summary["list"][index][GSI_SUBSYSTEM] = subSystemInfo
|
||||
if len(pciStatusClock) > 0 :
|
||||
summary["list"][index][GSI_CLOCK] = pciStatusClock
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
summary["list"][index][GSI_MODEL] = mapInfo["Model"].strip("\"")
|
||||
if GSI_NAME in summary["list"][index] :
|
||||
if GSI_MANUFACTURER in summary["list"][index] and \
|
||||
summary["list"][index][GSI_MANUFACTURER] != summary["list"][index][GSI_NAME] :
|
||||
summary["list"][index][GSI_MODEL] = summary["list"][index][GSI_NAME]
|
||||
else :
|
||||
if GSI_NAME in summary["list"][index] :
|
||||
summary["list"][index][GSI_MODEL] = summary["list"][index][GSI_NAME]
|
||||
|
||||
##NVIDIA显卡
|
||||
if "nvidia_name" in mapInfo :
|
||||
summary["list"][index][GSI_MODEL] = mapInfo["nvidia_name"]
|
||||
|
||||
##配置状态
|
||||
if "Config Status" in mapInfo :
|
||||
summary["list"][index][GSI_CONFSTATUS] = mapInfo["Config Status"]
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
summary["list"][index][GSI_DRIVER] = mapInfo["Driver"].strip("\"")
|
||||
|
||||
##驱动模块
|
||||
if "Driver Modules" in mapInfo :
|
||||
summary["list"][index][GSI_DRIVERMODULE] = mapInfo["Driver Modules"]
|
||||
|
||||
##设备
|
||||
if "Device" in mapInfo :
|
||||
summary["list"][index][GSI_DEVICE] = mapInfo["Device"]
|
||||
|
||||
index += 1
|
||||
|
||||
if Judgment_HW990() or len(summary["list"]) == 0 :
|
||||
displayList = self.get_display_hw990()
|
||||
if len(displayList) > 0 :
|
||||
summary["list"].append(displayList)
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self, customedType) :
|
||||
outLine = self.getGraphicsCardInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if 1 == customedType : ## lenovo
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
oneOutLine = ""
|
||||
if (GSI_MANUFACTURER in info and len(info[GSI_MANUFACTURER]) > 0) :
|
||||
gaManufacturer = exchangeManufacturer(info[GSI_MANUFACTURER])
|
||||
if gaManufacturer == "AMD" :
|
||||
oneOutLine += gaManufacturer+"-R520"
|
||||
elif gaManufacturer == "NV" :
|
||||
oneOutLine += gaManufacturer+"-GT730"
|
||||
elif gaManufacturer == "JJW" :
|
||||
oneOutLine += gaManufacturer+"-7201"
|
||||
elif gaManufacturer == "GLF" :
|
||||
oneOutLine += gaManufacturer+"-10C0"
|
||||
|
||||
if len(oneOutLine) > 0 :
|
||||
if nIndex == 0 :
|
||||
outLine += oneOutLine
|
||||
else :
|
||||
outLine += " / " + oneOutLine
|
||||
else :
|
||||
if GSI_NAME in info and len(info[GSI_NAME]) > 0:
|
||||
if nIndex == 0 :
|
||||
outLine += info[GSI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[GSI_NAME]
|
||||
elif MMI_MODEL in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[MMI_MODEL]
|
||||
else :
|
||||
outLine += " / " + info[MMI_MODEL]
|
||||
nIndex = nIndex + 1
|
||||
else :
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if GSI_NAME in info and len(info[GSI_NAME]) > 0:
|
||||
if nIndex == 0 :
|
||||
outLine += info[GSI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[GSI_NAME]
|
||||
elif MMI_MODEL in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[MMI_MODEL]
|
||||
else :
|
||||
outLine += " / " + info[MMI_MODEL]
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = KAGraphicsCardInfo(cmdTool)
|
||||
pprint(cc.getGraphicsCardInfo())
|
||||
#pprint(cc.getOutline())
|
|
@ -0,0 +1,381 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
class KAHarddiskInfo() :
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def get_human_read_capacity_size(self, size):
|
||||
size_str = ""
|
||||
displayed_size = 0.0
|
||||
unit = "KB"
|
||||
|
||||
if size < MEGABYTE_FACTOR:
|
||||
displayed_size = float(size/KILOBYTE_FACTOR)
|
||||
unit = "KB"
|
||||
elif size < GIGABYTE_FACTOR:
|
||||
displayed_size = float(size/MEGABYTE_FACTOR)
|
||||
unit = "MB"
|
||||
elif size < TERABYTE_FACTOR:
|
||||
displayed_size = float(size/GIGABYTE_FACTOR)
|
||||
unit = "GB"
|
||||
else:
|
||||
displayed_size = float(size/TERABYTE_FACTOR)
|
||||
unit = "TB"
|
||||
#print "displayed_size=", round(displayed_size)
|
||||
#round 不是简单的四舍五入,而是ROUND_HALF_EVEN的策略
|
||||
#ceil 取大于或者等于x的最小整数
|
||||
#floor 取小于或者等于x的最大整数
|
||||
#print round(2.5)#3.0
|
||||
#print math.ceil(2.5)#3.0
|
||||
#print math.floor(2.5)#2.0
|
||||
#print round(2.3)#2.0
|
||||
#print math.ceil(2.3)#3.0
|
||||
#print math.floor(2.3)#2.0
|
||||
if (unit == "TB"):
|
||||
str_list = [str(int(round(displayed_size, 1))), unit]
|
||||
else:
|
||||
str_list = [str(int(round(displayed_size))), unit]
|
||||
|
||||
size_str = " ".join(str_list)
|
||||
return size_str
|
||||
|
||||
def chkIsMainDisk(self, devName):
|
||||
if len(devName) <= 0 :
|
||||
return "0"
|
||||
status, output = subprocess.getstatusoutput("lsblk -b "+devName)
|
||||
if status :
|
||||
return "0"
|
||||
for line in output.split("\n"):
|
||||
value = line.split()
|
||||
if len(value) >= 7 and value[6]:
|
||||
if value[6] == "/" :
|
||||
return "1"
|
||||
return "0"
|
||||
|
||||
def chkIsSSD(self, devFileName):
|
||||
if len(devFileName) <= 0 :
|
||||
return "0"
|
||||
status, output = subprocess.getstatusoutput("lsblk -d -o name,rota")
|
||||
if status :
|
||||
return "0"
|
||||
for line in output.split("\n"):
|
||||
value = line.split()
|
||||
if len(value) >= 2 and value[1]:
|
||||
if value[0] == devFileName and value[1] == "0" :
|
||||
return "1"
|
||||
return "0"
|
||||
|
||||
def get_disk(self):
|
||||
disklist = []
|
||||
disk_manufacturers = {
|
||||
"ST": "Seagate",
|
||||
"IBM": "IBM",
|
||||
"HITACHI": "Hitachi",
|
||||
"IC": "Hitachi",
|
||||
"HTS": "Hitachi",
|
||||
"FUJITSU": "Fujitsu",
|
||||
"MP": "Fujitsu",
|
||||
"TOSHIBA": "Toshiba",
|
||||
"MK": "Toshiba",
|
||||
"MAXTOR": "Maxtor",
|
||||
"Pioneer": "Pioneer",
|
||||
"PHILIPS": "Philips",
|
||||
"QUANTUM": "Quantum",
|
||||
"FIREBALL": "Quantum",
|
||||
"WDC": "Western Digital",
|
||||
"HGST HUS": "Western Digital",
|
||||
"FORESEE": "Foresee",
|
||||
}
|
||||
|
||||
diskList = self.cmdTool.loadInfoFromHwinfo("--disk")
|
||||
self.cmdTool.loadDiskInfoFromLsblk()
|
||||
if "list" in diskList and len(diskList["list"]) > 0 :
|
||||
length = len(diskList["list"])
|
||||
for i in range(length) :
|
||||
if "SysFS BusID" in diskList["list"][i] :
|
||||
for mapInfo in self.cmdTool.lshwDiskList :
|
||||
if "bus info" in mapInfo :
|
||||
words = mapInfo["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip()
|
||||
key = key.replace(".",":")
|
||||
if key != diskList["list"][i]["SysFS BusID"] :
|
||||
continue
|
||||
diskList["list"][i].update(mapInfo)
|
||||
if "SysFS Device Link" in diskList["list"][i]:
|
||||
for mapInfo in self.cmdTool.lshwStorageList :
|
||||
if "bus info" in mapInfo :
|
||||
words = mapInfo["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip().lower()
|
||||
if key not in diskList["list"][i]["SysFS Device Link"].lower() :
|
||||
continue
|
||||
diskList["list"][i].update(mapInfo)
|
||||
for mapInfo in self.cmdTool.lsblkSmartList :
|
||||
if "dev_name" in mapInfo and "Device File" in diskList["list"][i] \
|
||||
and mapInfo["dev_name"] in diskList["list"][i]["Device File"] :
|
||||
diskList["list"][i].update(mapInfo)
|
||||
flag = Judgment_HW990()
|
||||
# 判断是否为联想定制
|
||||
customedType = Judgment_LENOVO()
|
||||
|
||||
for diskInfo in diskList["list"] :
|
||||
disk = {}
|
||||
DiskProduct,DiskVendor,DiskCapacity,DiskName,DiskFw,DiskSerial,DiskRota,DiskInterface = '','','','','','','',''
|
||||
devName = ""
|
||||
IsRemoveable = False
|
||||
if "dev_name" in diskInfo :
|
||||
devName = diskInfo["dev_name"]
|
||||
if "dev_majmin" in diskInfo :
|
||||
majorId = diskInfo["dev_majmin"].split(":")
|
||||
# 华为云硬盘主设备型号
|
||||
if len(majorId) == 2 and majorId[0] != "259" and majorId[0] != "8" and majorId[0] != "253" and majorId[0] != "252" :
|
||||
continue
|
||||
if flag and len(devName) > 0 :
|
||||
if "sda" == devName or "sdb" == devName or "sdc" == devName :
|
||||
continue
|
||||
if "Capacity" in diskInfo :
|
||||
DiskCapacity = diskInfo["Capacity"]
|
||||
result = re.findall("\((.*) bytes\)", DiskCapacity)
|
||||
DiskCapacity = re.sub("\(.*\)", "", DiskCapacity).replace(" ", "")
|
||||
if DiskCapacity.startswith("0") or DiskCapacity == "" :
|
||||
continue
|
||||
if result and len(result) > 0:
|
||||
if result[0].isdigit() :
|
||||
jinzhi = 1000.0
|
||||
if majorId[0] == "252" :
|
||||
jinzhi = 1024.0
|
||||
size = float(result[0])/jinzhi/jinzhi/jinzhi
|
||||
if size >= jinzhi :
|
||||
size = size/jinzhi
|
||||
DiskCapacity = str(float("%0.1f" % size))+"TB"
|
||||
else :
|
||||
DiskCapacity = str(int("%d" % size))+"GB"
|
||||
if len(DiskCapacity) == 0 and "size" in diskInfo :
|
||||
DiskCapacity = diskInfo["size"]
|
||||
result = re.findall(".*\((.*)\)$", DiskCapacity)
|
||||
if result and len(result) > 0 :
|
||||
DiskCapacity = result[0]
|
||||
capacity = ""
|
||||
if "User Capacity" in diskInfo :
|
||||
capacity = diskInfo["User Capacity"]
|
||||
if len(capacity) == 0 and "Total NVM Capacity" in diskInfo :
|
||||
capacity = diskInfo["Total NVM Capacity"]
|
||||
# bug#108169 1.02TB展示问题
|
||||
capacityTmp = capacity.replace("[","").replace("]","").split(" ")
|
||||
if "TB" in capacityTmp:
|
||||
capacity = capacityTmp[0]+" ["+ capacityTmp[-2].split(".")[0] + ".00" +" TB" +"]"
|
||||
if len(capacity) == 0 and "Namespace 1 Size/Capacity" in diskInfo :
|
||||
capacity = diskInfo["Namespace 1 Size/Capacity"]
|
||||
if len(capacity) > 0 :
|
||||
result = re.findall(".*\[(.*)\]$", capacity)
|
||||
if result and len(result) > 0 :
|
||||
DiskCapacity = result[0]
|
||||
if DiskCapacity.startswith("0") or DiskCapacity == "" :
|
||||
continue
|
||||
DiskName = ("/dev/" + devName)
|
||||
IsMainDisk = self.chkIsMainDisk(DiskName)
|
||||
IsSSD = "0"
|
||||
if "dev_rota" in diskInfo :
|
||||
if diskInfo["dev_rota"] == "0" :
|
||||
IsSSD = "1"
|
||||
else :
|
||||
IsSSD = "0"
|
||||
if "Rotation Rate" in diskInfo :
|
||||
if diskInfo["Rotation Rate"] == "Solid State Device" :
|
||||
IsSSD = "1"
|
||||
else :
|
||||
DiskRota = diskInfo["Rotation Rate"]
|
||||
if "dev_removeable" in diskInfo :
|
||||
IsRemoveable = (diskInfo["dev_removeable"] == "1")
|
||||
if "Vendor" in diskInfo :
|
||||
diskVendor = diskInfo["Vendor"].split("\"")
|
||||
if len(diskVendor) > 1 :
|
||||
DiskVendor = diskVendor[1]
|
||||
else :
|
||||
DiskVendor = diskInfo["Vendor"]
|
||||
if "SubVendor" in diskInfo :
|
||||
diskVendor = diskInfo["SubVendor"].split("\"")
|
||||
if len(diskVendor) > 1 :
|
||||
DiskVendor = diskVendor[1]
|
||||
else :
|
||||
DiskVendor = diskInfo["SubVendor"]
|
||||
if "vendor" in diskInfo :
|
||||
DiskVendor = diskInfo["vendor"]
|
||||
if len(DiskVendor) > 0 :
|
||||
for key, va in list(disk_manufacturers.items()):
|
||||
if DiskVendor.startswith(key):
|
||||
DiskVendor = va
|
||||
break
|
||||
if "serial" in diskInfo:
|
||||
DiskSerial = diskInfo["serial"]
|
||||
if "Serial Number" in diskInfo :
|
||||
DiskSerial = diskInfo["Serial Number"]
|
||||
if "Model" in diskInfo :
|
||||
DiskProduct = diskInfo["Model"]
|
||||
if "product" in diskInfo :
|
||||
DiskProduct = diskInfo["product"]
|
||||
if "Device Model" in diskInfo and len(diskInfo["Device Model"]) > 0 :
|
||||
DiskProduct = diskInfo["Device Model"]
|
||||
if "Model Number" in diskInfo and len(diskInfo["Model Number"]) > 0 :
|
||||
DiskProduct = diskInfo["Model Number"]
|
||||
if len(DiskProduct) > 0 :
|
||||
for key, va in list(disk_manufacturers.items()):
|
||||
if DiskProduct.startswith(key):
|
||||
DiskVendor = va
|
||||
break
|
||||
if "Firmware Version" in diskInfo :
|
||||
DiskFw = diskInfo["Firmware Version"]
|
||||
if "Attached to" in diskInfo :
|
||||
DiskInterface = diskInfo["Attached to"]
|
||||
interface = re.findall(".*\((.*)\).*", DiskInterface)
|
||||
if interface and len(interface) > 0 :
|
||||
DiskInterface = interface[0]
|
||||
DiskInterface = DiskInterface.replace("Controller", "").strip()
|
||||
DiskInterface = DiskInterface.replace("controller", "").strip()
|
||||
else:
|
||||
# 判断是否为SATA接口硬盘
|
||||
for mapInfo in self.cmdTool.lsblkSmartList :
|
||||
if "SATA Version" in mapInfo.keys() and "Device Model" in mapInfo.keys() and DiskProduct == mapInfo["Device Model"]:
|
||||
DiskInterface = "SATA"
|
||||
|
||||
if DiskInterface == "USB" and (len(DiskVendor) == 0 or "N/A" == DiskVendor or "USB" == DiskVendor) :
|
||||
if "usb_vendor" in diskInfo and "usb_device" in diskInfo :
|
||||
DiskVendor,_ = self.cmdTool.getUsbVendorProduct(diskInfo["usb_vendor"],diskInfo["usb_device"])
|
||||
print("vendorInfo:", DiskVendor,",",diskInfo["usb_vendor"],diskInfo["usb_device"])
|
||||
|
||||
if len(DiskCapacity) > 0 :
|
||||
disk[HDI_CAPACITY] = DiskCapacity
|
||||
if len(DiskName) > 0 :
|
||||
disk[HDI_NAME] = DiskName
|
||||
if len(DiskProduct) :
|
||||
disk[HDI_MODEL] = DiskProduct
|
||||
if len(DiskVendor) > 0 and DiskVendor != "USB" :
|
||||
disk[HDI_MANUFACTURER] = DiskVendor
|
||||
if len(DiskSerial) > 0 :
|
||||
disk[HDI_SERIALNUM] = DiskSerial;
|
||||
if len(DiskFw) > 0 :
|
||||
disk[HDI_FIRMWAREVER] = DiskFw
|
||||
disk[HDI_ISMAINDISK] = IsMainDisk
|
||||
if not IsRemoveable and "usb" not in DiskInterface.lower() :
|
||||
disk[HDI_ISSSD] = IsSSD
|
||||
disk[HDI_CANREMOVE] = False
|
||||
else :
|
||||
disk[HDI_CANREMOVE] = True
|
||||
if len(DiskRota) > 0 :
|
||||
disk[HDI_ROTA] = DiskRota
|
||||
if len(DiskInterface) > 0:
|
||||
disk[HDI_INTERFACE] = DiskInterface
|
||||
# 联想定制
|
||||
if(1 == customedType):
|
||||
disk[HDI_MODEL] = self.exchangeModel([disk])
|
||||
disklist.append(disk)
|
||||
|
||||
return disklist
|
||||
|
||||
#概要信息
|
||||
def getOutline(self, customedType) :
|
||||
outLineObj = self.get_disk()
|
||||
outLine = ""
|
||||
if 1 == customedType : ## lenovo
|
||||
|
||||
nIndex = 0
|
||||
for info in outLineObj :
|
||||
if HDI_CANREMOVE in info and info[HDI_CANREMOVE] :
|
||||
continue
|
||||
if nIndex != 0 :
|
||||
outLine += " / "
|
||||
outLine += self.exchangeModel([info])
|
||||
nIndex = nIndex + 1
|
||||
else:
|
||||
for info in outLineObj :
|
||||
if HDI_ISMAINDISK in info and info[HDI_ISMAINDISK] == '1':
|
||||
if HDI_MODEL in info :
|
||||
outLine += info[HDI_MODEL]
|
||||
if HDI_CAPACITY in info :
|
||||
outLine += "(" + info[HDI_CAPACITY]+")"
|
||||
break
|
||||
return outLine
|
||||
|
||||
#联想定制转换
|
||||
def exchangeModel(self, outLineObj):
|
||||
outLine = ""
|
||||
nIndex = 0
|
||||
for info in outLineObj :
|
||||
if HDI_CANREMOVE in info and info[HDI_CANREMOVE] :
|
||||
continue
|
||||
isSSD = False
|
||||
if nIndex != 0 :
|
||||
outLine += " / "
|
||||
if HDI_ISSSD in info and info[HDI_ISSSD] == '1' :
|
||||
outLine += "SSD"
|
||||
isSSD = True
|
||||
else :
|
||||
outLine += "HDD"
|
||||
if HDI_MANUFACTURER in info :
|
||||
diskManufacturer = exchangeManufacturer(info[HDI_MANUFACTURER])
|
||||
outLine += "-"+diskManufacturer
|
||||
if HDI_CAPACITY in info :
|
||||
tempCapacity = info[HDI_CAPACITY]
|
||||
tempCapacity = tempCapacity.replace("GB", "G")
|
||||
outLine += "-" + tempCapacity
|
||||
if isSSD :
|
||||
outLine += "-PCIe"
|
||||
else :
|
||||
outLine += "-SATA"
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = KAHarddiskInfo(cmdTool)
|
||||
pprint(cc.get_disk())
|
||||
# pprint(cc.getOutline(1))
|
||||
# if __name__ == "__main__":
|
||||
# capacity = "1,024,209,543,168 [1.02 TB]"
|
||||
# # bug#108169
|
||||
# capacityTmp = capacity.replace("[","").replace("]","").split(" ");
|
||||
# if "TB" in capacityTmp[-1]:
|
||||
# print(capacityTmp)
|
||||
# print(capacityTmp[-1].split(" "))
|
||||
# # capacity = capacityTmp[0].split(".")[0] + ".00"+" TB"
|
||||
# #print(capacity)
|
|
@ -0,0 +1,447 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from subprocess import PIPE
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
from gi.repository import GLib
|
||||
|
||||
import subprocess
|
||||
|
||||
from karealization import *
|
||||
from kapolicykit import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
from memoryinfothread import MemoryInfo
|
||||
from networkadaptorthread import NetworkAdaptor
|
||||
from audioadaptorthread import AudioAdaptor
|
||||
from kamonitorthread import KAMonitor
|
||||
from kaharddiskinfo import KAHarddiskInfo
|
||||
from kagraphicscardinfo import KAGraphicsCardInfo
|
||||
from systemboardthread import *
|
||||
from kakeyboardinfo import KAKeyboardInfo
|
||||
from kamouseinfo import KAMouseInfo
|
||||
from kacdrominfo import KACDRomInfo
|
||||
from kamachineinfo import KAMachineInfo
|
||||
from kabluetoothinfo import KABluetoothInfo
|
||||
from kafaninfo import KAFanInfo
|
||||
from kacmdtool import KACmdTool
|
||||
from kacamerainfo import KACameraInfo
|
||||
from kabatteryinfo import KABatteryInfo
|
||||
|
||||
OBJPATH = '/com/kylin/assistant/systemdaemon'
|
||||
INTERFACE = 'com.kylin.assistant.systemdaemon'
|
||||
|
||||
THREAD_INDEX_OUTLINE = 0
|
||||
THREAD_INDEX_HARDWARE = 1
|
||||
THREAD_INDEX_MEMORY = 2
|
||||
THREAD_INDEX_NETWORK = 3
|
||||
THREAD_INDEX_AUDIOADAPTER = 4
|
||||
THREAD_INDEX_SYSTEMBOARD = 5
|
||||
THREAD_INDEX_RELOADLSHW = 6
|
||||
THREAD_INDEX_MAX = 7
|
||||
|
||||
class HardwareInfo(dbus.service.Object):
|
||||
def __init__(self, system_bus, mainloop):
|
||||
# Init dbus service.
|
||||
dbus.service.Object.__init__(self, system_bus, OBJPATH)
|
||||
self.mainloop = mainloop
|
||||
|
||||
self.policykitservice = PolicyKitService()
|
||||
|
||||
self.hwobj = DetailInfo()
|
||||
|
||||
self.cmdtool = KACmdTool()
|
||||
#self.cmdtool.loadInfoFromLshw()
|
||||
|
||||
self.threadPool = [None] * THREAD_INDEX_MAX
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='', sender_keyword='sender')
|
||||
def exit(self, sender = None):
|
||||
self.mainloop.quit()
|
||||
|
||||
@dbus.service.signal(INTERFACE, signature='s')
|
||||
def signalGettingInfo(self, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def mdObtainProcessorInfo(self, sender=None):
|
||||
return self.hwobj.getProcessorInfo()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def mdObtainMemoryInfo(self, sender=None):
|
||||
self.threadPool[THREAD_INDEX_MEMORY] = KAThread(MemoryInfo(self.cmdtool).getMemInfo, None, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_MEMORY].start()
|
||||
self.threadPool[THREAD_INDEX_MEMORY].join()
|
||||
return self.threadPool[THREAD_INDEX_MEMORY].getResult()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def mdObtainNetworkAdaptorInfo(self, sender=None):
|
||||
self.threadPool[THREAD_INDEX_NETWORK] = KAThread(NetworkAdaptor(self.cmdtool).getNetworkAdaptorInfo, None, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_NETWORK].start()
|
||||
self.threadPool[THREAD_INDEX_NETWORK].join()
|
||||
return self.threadPool[THREAD_INDEX_NETWORK].getResult()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def mdObtainAudioAdaptorInfo(self, sender=None):
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER] = KAThread(AudioAdaptor(self.cmdtool).getAudioAdaptorInfo, None, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER].start()
|
||||
self.threadPool[THREAD_INDEX_AUDIOADAPTER].join()
|
||||
return self.threadPool[THREAD_INDEX_AUDIOADAPTER].getResult()
|
||||
|
||||
# harddisk
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalHDUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readHDInfo(self, sender=None):
|
||||
harddiskInfo = KAHarddiskInfo(self.cmdtool)
|
||||
hdInfo = {"list":harddiskInfo.get_disk()}
|
||||
strJson = json.dumps(hdInfo)
|
||||
return strJson
|
||||
|
||||
#memory info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalMemUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readMemInfo(self, sender=None):
|
||||
memObj = MemoryInfo(self.cmdtool)
|
||||
memInfo = memObj.getMemInfo()
|
||||
return memInfo
|
||||
|
||||
#processor info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalProcUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readProcInfo(self, sender=None):
|
||||
return self.hwobj.getProcessorInfo()
|
||||
|
||||
#network card info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalNWUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readNWInfo(self, sender=None):
|
||||
return self.mdObtainNetworkAdaptorInfo()
|
||||
|
||||
#voice card info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalVCUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readVCInfo(self, sender=None):
|
||||
return self.mdObtainAudioAdaptorInfo()
|
||||
|
||||
#mother board info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalMBUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readMBInfo(self, sender=None):
|
||||
motherBoard = {}
|
||||
systemBoardInfo = SystemBoard()
|
||||
boardInfo = systemBoardInfo.getBaseBoardInfo()
|
||||
if Board_Manufacturer in boardInfo :
|
||||
motherBoard[MBI_MANUFACTURER] = boardInfo[Board_Manufacturer]
|
||||
if Board_Product in boardInfo :
|
||||
motherBoard[MBI_NAME] = boardInfo[Board_Product]
|
||||
if Board_Chipset in boardInfo :
|
||||
motherBoard[MBI_CHIPSET] = boardInfo[Board_Chipset]
|
||||
if Board_Version in boardInfo :
|
||||
motherBoard[MBI_VERSION] = boardInfo[Board_Version]
|
||||
if Board_Serial in boardInfo :
|
||||
motherBoard[MBI_SERIALNUM] = boardInfo[Board_Serial]
|
||||
biosInfo = systemBoardInfo.getBiosInfo()
|
||||
if BIOS_Manufacturer in biosInfo :
|
||||
motherBoard[MBI_BIOSMANUFACTURER] = biosInfo[BIOS_Manufacturer]
|
||||
if BIOS_Version in biosInfo :
|
||||
motherBoard[MBI_BIOSVERSION] = biosInfo[BIOS_Version]
|
||||
if BIOS_ReleaseDate in biosInfo :
|
||||
motherBoard[MBI_PUBDATE] = biosInfo[BIOS_ReleaseDate]
|
||||
strJson = json.dumps(motherBoard)
|
||||
return strJson
|
||||
|
||||
#graphics info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalGSUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readGSInfo(self, sender=None):
|
||||
graphicsCard = KAGraphicsCardInfo(self.cmdtool)
|
||||
return graphicsCard.getGraphicsCardInfo()
|
||||
|
||||
#bluetooth info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalBLUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readBLInfo(self, sender=None):
|
||||
bluetoothInfo = KABluetoothInfo(self.cmdtool)
|
||||
return bluetoothInfo.getBluetoothInfo()
|
||||
|
||||
#keyboard info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalKBUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readKBInfo(self, sender=None):
|
||||
keyBoard = KAKeyboardInfo(self.cmdtool)
|
||||
return keyBoard.getkeyboardInfo()
|
||||
|
||||
#mouse info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalMSUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readMSInfo(self, sender=None):
|
||||
mouse = KAMouseInfo(self.cmdtool)
|
||||
return mouse.getMouseInfo()
|
||||
|
||||
#monitor info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalMNUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readMNInfo(self, sender=None):
|
||||
monitorInfo = KAMonitor()
|
||||
return monitorInfo.getMonitorsInfo()
|
||||
|
||||
#cddrive info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalCDUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readCDInfo(self, sender=None):
|
||||
cdrom = KACDRomInfo()
|
||||
return cdrom.getCDRomInfo()
|
||||
|
||||
#battery info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalBTUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readBTInfo(self, sender=None):
|
||||
battery = KABatteryInfo()
|
||||
sysBoardInfo = SystemBoard()
|
||||
sysInfo = sysBoardInfo.getSystemInfo()
|
||||
if System_Product in sysInfo and sysInfo[System_Product] != "XXXX" :
|
||||
return battery.getBatteryInfo(sysInfo[System_Product])
|
||||
else :
|
||||
return battery.getBatteryInfo()
|
||||
|
||||
#camera info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalCAUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readCAInfo(self, sender=None):
|
||||
camera = KACameraInfo(self.cmdtool)
|
||||
return camera.getCameraInfo()
|
||||
|
||||
#fan info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalFAUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readFAInfo(self, sender=None):
|
||||
faninfo = KAFanInfo()
|
||||
return faninfo.getFanInfo()
|
||||
|
||||
#all info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalHardwareUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
def getHardwareInfo(self):
|
||||
hardwareInfo = {}
|
||||
infoItem = self.readHDInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[HDI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readMemInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[MMI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readProcInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[PSI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readNWInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[NWI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readVCInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[VCI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readMBInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[MBI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readGSInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[GSI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readBLInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[BLI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readKBInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[KBI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readMSInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[MSI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readMNInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[MNI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readCDInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[CDI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readBTInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[BTI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readCAInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[CAI_ROOT] = json.loads(infoItem)
|
||||
infoItem = self.readFAInfo()
|
||||
if len(infoItem) > 0 :
|
||||
hardwareInfo[FAI_ROOT] = json.loads(infoItem)
|
||||
strJson = json.dumps(hardwareInfo)
|
||||
return strJson
|
||||
|
||||
#all info
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readHardwareInfo(self, sender=None):
|
||||
if self.threadPool[THREAD_INDEX_HARDWARE] and self.threadPool[THREAD_INDEX_HARDWARE].is_alive() :
|
||||
return self.threadPool[THREAD_INDEX_HARDWARE].getResult()
|
||||
self.updateLshwInfo(True)
|
||||
self.threadPool[THREAD_INDEX_HARDWARE] = KAThread(self.getHardwareInfo, self.signalHardwareUpdateInfo, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_HARDWARE].start()
|
||||
return self.threadPool[THREAD_INDEX_HARDWARE].getResult()
|
||||
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def mdObtainSystemBoardInfo(self, sender=None):
|
||||
self.threadPool[THREAD_INDEX_SYSTEMBOARD] = KAThread(SystemBoard().getSystemBoardInfo, None, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_SYSTEMBOARD].start()
|
||||
self.threadPool[THREAD_INDEX_SYSTEMBOARD].join()
|
||||
return self.threadPool[THREAD_INDEX_SYSTEMBOARD].getResult()
|
||||
|
||||
#machine outline info
|
||||
@dbus.service.signal(INTERFACE, signature='us')
|
||||
def signalOutlineUpdateInfo(self, status, msg):
|
||||
pass
|
||||
|
||||
def getOutlineInfo(self):
|
||||
outline = KAMachineInfo(self.cmdtool)
|
||||
return outline.getOutline()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s', sender_keyword='sender')
|
||||
def readOutline(self, sender=None):
|
||||
if self.threadPool[THREAD_INDEX_OUTLINE] and self.threadPool[THREAD_INDEX_OUTLINE].is_alive() :
|
||||
return self.threadPool[THREAD_INDEX_OUTLINE].getResult()
|
||||
self.updateLshwInfo(False)
|
||||
self.threadPool[THREAD_INDEX_OUTLINE] = KAThread(self.getOutlineInfo, self.signalOutlineUpdateInfo, args=())
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_OUTLINE].start()
|
||||
return self.threadPool[THREAD_INDEX_OUTLINE].getResult()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='a{sv}')
|
||||
def get_cpu_info(self):
|
||||
cpuInfo = DetailInfo()
|
||||
return cpuInfo.get_cpu()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='b')
|
||||
def hide_temperature_page(self):
|
||||
status, output = subprocess.getstatusoutput("sensors")
|
||||
if( status != -1 ):
|
||||
for line in output.split("\n"):
|
||||
if "coretemp-isa" in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='b')
|
||||
def hide_fan_page(self):
|
||||
faninfo = KAFanInfo()
|
||||
return faninfo.getCpuFanEnable()
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='b')
|
||||
def hide_cpufm_page(self):
|
||||
path = '/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq'
|
||||
if os.path.exists(path):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@dbus.service.signal(INTERFACE, signature='')
|
||||
def signalLshwUpdateFinished(self):
|
||||
pass
|
||||
|
||||
def signalLshwReloadFinished(self, status, isDone):
|
||||
self.signalLshwUpdateFinished()
|
||||
pass
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='b', sender_keyword='sender')
|
||||
def updateLshwInfo(self, forceUpdate = True, sender=None):
|
||||
self.cmdtool.loadInfoFromLshw(forceUpdate)
|
||||
return True
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='b', sender_keyword='sender')
|
||||
def reloadLshwInfo(self, forceUpdate = True, sender=None):
|
||||
if self.threadPool[THREAD_INDEX_RELOADLSHW] and self.threadPool[THREAD_INDEX_RELOADLSHW].is_alive() :
|
||||
return True
|
||||
args = {forceUpdate}
|
||||
self.threadPool[THREAD_INDEX_RELOADLSHW] = KAThread(self.cmdtool.loadInfoFromLshw, self.signalLshwReloadFinished, args=(args))
|
||||
#改为信号的方式
|
||||
self.threadPool[THREAD_INDEX_RELOADLSHW].start()
|
||||
return True
|
||||
|
||||
if __name__ == '__main__':
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
mainloop = GLib.MainLoop()
|
||||
# Init dbus.
|
||||
system_bus = dbus.SystemBus()
|
||||
bus_name = dbus.service.BusName("com.kylin.assistant.systemdaemon", system_bus)
|
||||
HardwareInfo(system_bus, mainloop)
|
||||
mainloop.run()
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
from kacmdtool import KACmdTool
|
||||
|
||||
###Machine Outline
|
||||
MI_MANUFACTURER = "Manufacturer" #整机制造商
|
||||
MI_MACHINEMODEL = "MachineModel" #整机型号
|
||||
MI_SERIALNUM = "SerialNum" #SN
|
||||
MI_VERSION = "Version" #整机版本
|
||||
MI_SYSTEMBITS = "SystemBits" #系统位数
|
||||
MI_KERNELARCH = "KernelArch" #内核架构
|
||||
MI_KERNELVERSION = "KernelVersion" #内核版本
|
||||
MI_HOSTNAME = "HostName" #主机名
|
||||
MI_OSVERSION = "OSVersion" #操作系统版本
|
||||
MI_OSTYPES = "OS Types" #操作系统类型
|
||||
MI_RUNINGTIME = "Running Time" #系统持续运行时间
|
||||
MI_PROCESSOR = "Processor" #处理器
|
||||
MI_MEMORY = "Memory" #内存
|
||||
MI_MAINBOARD = "MainBoard" #主板
|
||||
MI_HARDDISK = "HardDisk" #硬盘
|
||||
MI_GRAPHICSCARD = "GraphicsCard" #显卡
|
||||
MI_MONITOR = "Monitor" #显示器
|
||||
MI_NETWORKCARD = "NetworkCard" #网卡
|
||||
MI_SOUNDCARD = "SoundCard" #声卡
|
||||
|
||||
##PROCESSOR
|
||||
Pro_Manufacturer= "manufacturer"
|
||||
Pro_Product= "processor"
|
||||
Pro_Architecture= "architecture"
|
||||
Pro_Frequency= "fref"
|
||||
Pro_Frequency_Max= "fref_max"
|
||||
Pro_Threads= "threads_num"
|
||||
Pro_Family= "Family"
|
||||
Pro_Model= "Model"
|
||||
Pro_Stepping= "Stepping"
|
||||
Pro_L1dCache= "L1d_cache"
|
||||
Pro_L1iCache= "L1i_cache"
|
||||
Pro_L2Cache= "L2_cache"
|
||||
Pro_L3Cache= "L3_cache"
|
||||
Pro_Cores= "cores_num"
|
||||
Pro_Cores_Online= "cores_num_online"
|
||||
Pro_Ext_Instruction_Set="ext_instruction_set"
|
||||
PSI_ROOT = "processor" #处理器根
|
||||
|
||||
##MEMORY
|
||||
Mem_Manufacturer= "Manufacturer"
|
||||
Mem_BankLocator= "Bank Locator"
|
||||
Mem_Type= "Type"
|
||||
Mem_TypeDetail= "Type Detail"
|
||||
Mem_TotalWidth= "Total Width"
|
||||
Mem_DataWidth= "Data Width"
|
||||
Mem_SerialNumber= "Serial Number"
|
||||
Mem_MinVoltage= "Minimum Voltage"
|
||||
Mem_MaxVoltage= "Maximum Voltage"
|
||||
Mem_ConfVoltage= "Configured Voltage"
|
||||
Mem_Rank= "Rank"
|
||||
Mem_FormFactor= "Form Factor"
|
||||
Mem_Product= "Product"
|
||||
|
||||
MMI_ROOT = "memory" #内存
|
||||
MMI_SLOT = "slot" #插槽
|
||||
MMI_NAME = "name" #名称
|
||||
MMI_FREQ = "freq" #当前频率
|
||||
MMI_BUSWIDTH = "bus_width" #总线位宽
|
||||
MMI_DATAWIDTH = "data_width" #数据位宽
|
||||
MMI_TYPE = "type" #类型
|
||||
MMI_TOTALCAPACITY = "total_capacity" #总容量
|
||||
MMI_USEDCAPACITY = "used_capacity" #已用容量
|
||||
MMI_SERIALNUM = "serail_num" #序列号
|
||||
MMI_MANUFACTURER = "manufacturer" #制造商
|
||||
MMI_MODEL = "model" #型号
|
||||
MMI_SPEED = "speed" #速率
|
||||
MMI_CONFIGSPEED = "config_speed" #配置速率
|
||||
MMI_PIPE = "pipe" #通道
|
||||
MMI_ARRAYHANDLE = "array_handle" #数组程序
|
||||
MMI_PARTNUMBER = "partnum" #部件号码
|
||||
MMI_PHYSICALID = "physicalid" #物理ID
|
||||
|
||||
###HARD DISK
|
||||
HDI_ROOT = "harddisk" #硬盘
|
||||
HDI_MANUFACTURER = "manufacturer" #硬盘品牌
|
||||
HDI_NAME = "name" #名称
|
||||
HDI_CAPACITY = "capacity" #容量
|
||||
HDI_USEDTIMES = "used_times" #已使用次数
|
||||
HDI_INTERFACE = "interface" #接口
|
||||
HDI_ISMAINDISK = "is_maindisk" #主硬盘(是否)
|
||||
HDI_ISSSD = "is_ssd" #硬盘类型(固态/机械)
|
||||
HDI_CANREMOVE = "can_remove" #可移除
|
||||
HDI_SERIALNUM = "serial_num" #序列号
|
||||
HDI_MODEL = "model" #型号
|
||||
HDI_TRANSRATE = "trans_rate" #数据传输率
|
||||
HDI_READSPEED = "read_speed" #磁盘读取速度
|
||||
HDI_WRITESPEED = "write_speed" #磁盘写入速度
|
||||
HDI_FIRMWAREVER = "firmware_ver" #固件版本
|
||||
HDI_ROTA = "rota" #机械转速
|
||||
|
||||
###DEV MONITOR
|
||||
DEVMONITOR_ROOT = "device_monitor" #设备监测
|
||||
DEVMONITOR_DEVTEMP = "device_temp" #设备温度
|
||||
DEVMONITOR_DEVTEMPS = "device_temps" #设备温度列表
|
||||
DEVMONITOR_DEVTEMP_HIGH = "device_temp_high" #设备高温
|
||||
DEVMONITOR_DEVTEMP_CRIT = "device_temp_crit" #设备异常温
|
||||
DEVMONITOR_DEVTEMP_NAME = "device_name" #设备名称
|
||||
DEVMONITOR_DEVTEMP_VALUE = "device_temp_value" #设备温度值
|
||||
DEVMONITOR_DEVUSAGE = "device_usage" #设备使用率
|
||||
DEVMONITOR_DEVUSAGE_NAME = "device_name" #设备名称
|
||||
DEVMONITOR_DEVUSAGE_USED = "device_usage_used" #设备使用率
|
||||
DEVMONITOR_DEVUSAGE_TOTAL = "device_usage_total" #使用总值
|
||||
|
||||
###CPU FM
|
||||
Cpufm_Root = "cpu_fm" # cpu调频
|
||||
Cpufm_Average_Corefreq = "cpu_corefreq" #当前cpu核心平均主频
|
||||
Cpufm_Models = "cpu_model_list" #cpu调频模式列表
|
||||
Cpufm_Current_Model = "cpu_curmodel" #cpu当前模式
|
||||
Cpufm_Model_Performance = "performance" #性能模式
|
||||
Cpufm_Model_Powersave = "powersave" #省电模式
|
||||
Cpufm_Model_Userspace = "userspace" #自定义
|
||||
Cpufm_Model_Schedutil = "schedutil" #均衡模式
|
||||
Cpufm_Freqs = "cpu_freq_list" #cpu频率列表
|
||||
Cpufm_CurFreq = "cur_freq" #cpu调频
|
||||
|
||||
###NETWORK CARD
|
||||
NWI_ROOT = "network_card" #网卡
|
||||
|
||||
###VOICE CARD
|
||||
VCI_ROOT = "voice_card" #声卡
|
||||
|
||||
###MOTHER BOARD
|
||||
MBI_ROOT= "mother_board" #主板
|
||||
MBI_NAME= "name" #主板名称
|
||||
MBI_CHIPSET= "chipset" #芯片组
|
||||
MBI_SERIALNUM= "serial_num" #序列号
|
||||
MBI_PUBDATE= "publish_date" #发布日期
|
||||
MBI_VERSION= "version" #主板版本
|
||||
MBI_MANUFACTURER= "manufacturer" #主板制造商
|
||||
MBI_BIOSMANUFACTURER= "bios_manufacturer" #BIOS制造商
|
||||
MBI_BIOSVERSION= "bios_version" #BIOS版本
|
||||
|
||||
###GRAPHICS CARD
|
||||
GSI_ROOT= "graphics_card" #显卡
|
||||
GSI_MANUFACTURER= "manufacturer" #厂商
|
||||
GSI_SUBSYSTEM= "subsystem" #子制造商
|
||||
GSI_NAME= "name" #名称
|
||||
GSI_ISDISCRETE= "is_discrete" #是否为独显
|
||||
GSI_CAPCITY= "capcity" #显存
|
||||
GSI_MEMTYPE= "mem_type" #显存类型
|
||||
GSI_MODEL= "model" #型号
|
||||
GSI_VERSION= "version" #版本
|
||||
GSI_BITWIDTH= "bit_width" #位宽
|
||||
GSI_IRQ= "irq" #中断
|
||||
GSI_FUNCTION= "function" #功能
|
||||
GSI_CLOCK= "clock" #时钟频率
|
||||
GSI_DESC= "description" #描述
|
||||
GSI_DRIVER= "driver" #驱动
|
||||
GSI_DBUSINFO= "dbusinfo" #总线信息
|
||||
GSI_IOPORT= "io_port" #I/O端口
|
||||
GSI_MEMORY= "memory" #内存
|
||||
GSI_PHYSICS= "physics_id" #物理ID
|
||||
GSI_DELAY= "delay" #延迟
|
||||
GSI_DEVICE= "device" #设备
|
||||
GSI_CONFSTATUS= "config_status" #配置状态
|
||||
GSI_DRIVERMODULE= "driver_module" #驱动模块
|
||||
GSI_GDDRCAPACITY= "gddr_capacity" #GDDR容量
|
||||
GSI_EGLVERSION= "egl_version" #EGL版本
|
||||
GSI_EGLAPIS= "egl_apis" #EGL接口
|
||||
GSI_GLVERSION= "gl_version" #GL版本
|
||||
GSI_GLSLVERSION= "glsl_version" #GLSL版本
|
||||
|
||||
###MONITOR
|
||||
MNI_ROOT= "monitor" #显示器
|
||||
MNI_MANUFACTURER= "manufacturer" #显示器厂商
|
||||
MNI_NAME= "name" #名称
|
||||
MNI_SIZE= "size" #屏幕尺寸
|
||||
MNI_RATIO= "ratio" #图像高宽比
|
||||
MNI_RESOLUTION= "resolution" #分辨率
|
||||
MNI_MAXAVARES= "max_resolution" #最大分辨率
|
||||
MNI_ISMAIN= "is_main" #主显示器(是/否)
|
||||
MNI_GAMMA= "gamma" #伽马值
|
||||
MNI_INTERFACE= "interface" #当前接口
|
||||
MNI_MODEL= "model" #型号
|
||||
MNI_VISIBLEAREA= "visible_area" #可视面积
|
||||
MNI_YEAR= "year" #生产年
|
||||
MNI_WEEK= "week" #生产周
|
||||
MNI_SERIALNUM= "serailnum" #序列号
|
||||
|
||||
###KEYBOARD
|
||||
KBI_ROOT= "key_board" #键盘
|
||||
KBI_DEVTYPE= "dev_type" #设备类型
|
||||
KBI_NAME= "name" #设备名称
|
||||
KBI_DEVMODEL= "dev_model" #设备型号
|
||||
KBI_MANUFACTURER= "manufacturer" #制造商
|
||||
KBI_INTERFACE= "interface" #接口
|
||||
KBI_DRIVER= "driver" #驱动
|
||||
|
||||
###MOUSE
|
||||
MSI_ROOT= "mouse" #鼠标
|
||||
MSI_DEVTYPE= "dev_type" #设备类型
|
||||
MSI_NAME= "name" #设备名称
|
||||
MSI_DEVMODEL= "dev_model" #设备型号
|
||||
MSI_MANUFACTURER= "manufacturer" #制造商
|
||||
MSI_INTERFACE= "interface" #接口
|
||||
MSI_DRIVER= "driver" #驱动
|
||||
|
||||
###BATTERY
|
||||
BTI_ROOT= "battery" #电池
|
||||
BTI_NAME= "name" #名称
|
||||
BTI_SERAILNUM= "serailnum" #序列号
|
||||
BTI_MODEL= "model" #型号
|
||||
BTI_MANUFACTURER= "manufacturer" #制造商
|
||||
BTI_TTE= "time_to_empty" #预计使用时间
|
||||
BTI_USEDTIMES= "used_times" #使用次数
|
||||
BTI_ENERGYFULL= "energy_full" #满电容量
|
||||
BTI_ENERGY= "energy" #当前容量
|
||||
BTI_STATE= "state" #状态
|
||||
BTI_PERCENTAGE= "percentage" #电量
|
||||
|
||||
###CDDRIVE
|
||||
CDI_ROOT= "cddrive" #光驱
|
||||
CDI_NAME= "name" #名称
|
||||
CDI_MANUFACTURER= "manufacturer" #制造商
|
||||
CDI_VERSION= "version" #版本
|
||||
CDI_MODEL= "model" #型号
|
||||
CDI_BUSINFO= "businfo" #总线信息
|
||||
CDI_DRIVER= "driver" #驱动
|
||||
CDI_SPEED= "speed" #速度
|
||||
CDI_SERAILNUM= "serailnum" #序列号
|
||||
CDI_DEVICENUM= "devicenum" #设备编号
|
||||
|
||||
CAI_ROOT= "camera" #摄像头
|
||||
CAI_NAME= "name" #设备名称
|
||||
CAI_RESOLUTION= "resolution" #分辨率
|
||||
CAI_MANUFACTURER= "manufacturer" #制造商
|
||||
CAI_MODEL= "model" #型号
|
||||
CAI_INTERFACE= "interface" #接口
|
||||
CAI_DRIVER= "driver" #驱动
|
||||
CAI_TYPE= "type" #类型
|
||||
CAI_VERSION= "version" #版本
|
||||
CAI_BUSINFO= "businfo" #总线信息
|
||||
CAI_SPEED= "speed" #速度
|
||||
|
||||
###BLUETOOTH
|
||||
BLI_ROOT= "bluetooth" #蓝牙
|
||||
BLI_BUSADDR= "bus_addr" #总线地址
|
||||
BLI_FUNCTION= "function" #功能
|
||||
BLI_FREQ= "freq" #频率
|
||||
BLI_CONF= "configuration" #配置
|
||||
BLI_DEVTYPE= "dev_type" #设备类型
|
||||
BLI_ID= "id" #ID号
|
||||
BLI_DEVMODEL= "dev_model" #设备型号
|
||||
BLI_RESOURCE= "resource" #资源
|
||||
BLI_MANUFACTURER= "manufacturer" #制造商
|
||||
BLI_DEVVERSION= "dev_version" #设备版本
|
||||
BLI_DATAWIDTH= "data_width" #数据宽度
|
||||
BLI_NAME= "name" #名称
|
||||
BLI_DRIVER= "driver" #驱动
|
||||
BLI_SPEED= "speed" #速度
|
||||
BLI_SERIALNUM= "serial_num" #序列号
|
||||
BLI_ADDRESS= "address" #蓝牙地址
|
||||
BLI_LINKMODE= "link_mode" #连接模式
|
||||
BLI_LINKPOLICY= "link_policy" #连接策略
|
||||
BLI_PRODUCT= "product" #产品
|
||||
BLI_CAPABILITIES= "capabilities" #功能
|
||||
BLI_BUS= "bus" #总线
|
||||
BLI_SCOMTU= "scomtu" #SCO MTU
|
||||
BLI_ALCMTU= "alcmtu" #ACL MTU
|
||||
BLI_PACKETTYPE= "packettype" #数据包类型
|
||||
BLI_FEATURES= "features" #特征
|
||||
|
||||
###FAN
|
||||
FAI_ROOT= "fan" #风扇
|
||||
FAI_NAME= "name" #名称
|
||||
FAI_SPEED= "speed" #转速
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
class KAKeyboardInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getkeyboardInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
hwinfoList = self.cmdTool.loadInfoFromHwinfo("--keyboard")["list"]
|
||||
for mapInfo in hwinfoList :
|
||||
if len(mapInfo) == 0 :
|
||||
continue
|
||||
kbName,kbManufacturer,kbModel,kbInterface,kbDriver,kbType = "","","","","",""
|
||||
kbOne = {}
|
||||
##名称
|
||||
if "Device" in mapInfo :
|
||||
kbDevice = mapInfo["Device"].split("\"")
|
||||
if len(kbDevice) > 1 :
|
||||
kbName = kbDevice[1]
|
||||
else :
|
||||
kbName = mapInfo["Device"]
|
||||
|
||||
##AT Raw键盘
|
||||
if "AT Raw" in kbName:
|
||||
continue;
|
||||
##panguw键盘
|
||||
if "lsadc" in kbName:
|
||||
continue;
|
||||
##类型
|
||||
if "Hardware Class" in mapInfo :
|
||||
kbType = mapInfo["Hardware Class"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
kbVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(kbVendor) > 1 :
|
||||
kbManufacturer = kbVendor[1]
|
||||
else :
|
||||
kbManufacturer = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
kbVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(kbVendor) > 1 :
|
||||
kbManufacturer = kbVendor[1]
|
||||
else :
|
||||
kbManufacturer = mapInfo["SubVendor"]
|
||||
|
||||
##接口
|
||||
if "Hotplug" in mapInfo :
|
||||
kbInterface = mapInfo["Hotplug"]
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
kbModel = mapInfo["Model"].strip("\"")
|
||||
if "bluetooth" in kbModel :
|
||||
kbInterface = "BLUETOOTH"
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
kbDriver = mapInfo["Driver"].strip("\"")
|
||||
|
||||
if len(kbName) > 0 :
|
||||
kbOne[KBI_NAME] = kbName
|
||||
if len(kbType) > 0 :
|
||||
kbOne[KBI_DEVTYPE] = kbType
|
||||
if len(kbManufacturer) > 0 :
|
||||
kbOne[KBI_MANUFACTURER] = kbManufacturer
|
||||
if len(kbInterface) > 0 :
|
||||
kbOne[KBI_INTERFACE] = kbInterface
|
||||
if len(kbModel) > 0 :
|
||||
kbOne[KBI_DEVMODEL] = kbModel
|
||||
if len(kbDriver) > 0 :
|
||||
kbOne[KBI_DRIVER] = kbDriver
|
||||
|
||||
if len(kbOne) > 0 :
|
||||
summary["list"].append(kbOne)
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getkeyboardInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if KBI_NAME in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[KBI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[KBI_NAME]
|
||||
if KBI_DEVMODEL in info :
|
||||
outLine += "("+info[KBI_DEVMODEL]+")"
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cc = KAKeyboardInfo(cmdTool)
|
||||
pprint(cc.getkeyboardInfo())
|
||||
#pprint(cc.getOutline())
|
|
@ -0,0 +1,428 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import platform
|
||||
import binascii
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from systemboardthread import *
|
||||
|
||||
from karealization import DetailInfo
|
||||
from memoryinfothread import MemoryInfo
|
||||
from networkadaptorthread import NetworkAdaptor
|
||||
from audioadaptorthread import AudioAdaptor
|
||||
from kamonitorthread import KAMonitor
|
||||
from kaharddiskinfo import KAHarddiskInfo
|
||||
from kagraphicscardinfo import KAGraphicsCardInfo
|
||||
from systemboardthread import *
|
||||
from kakeyboardinfo import KAKeyboardInfo
|
||||
from kamouseinfo import KAMouseInfo
|
||||
from kacdrominfo import KACDRomInfo
|
||||
|
||||
class KAMachineInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.osname = self.read_os_name()
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def ctoascii(self,buf):
|
||||
ch = bytes(buf.encode('utf-8'))
|
||||
asci = binascii.b2a_hex(ch)
|
||||
asci = int(asci,16)
|
||||
return asci
|
||||
|
||||
def strip(self, s):
|
||||
if(len(s) == 0):
|
||||
return s
|
||||
while len(s) > 0 and self.ctoascii(s[0]) <= 32:
|
||||
s = s[1: ]
|
||||
k = len(s)
|
||||
while len(s) > 0 and self.ctoascii(s[k-1]) <= 32:
|
||||
s = s[ :k-1]
|
||||
k = len(s)
|
||||
i = 0
|
||||
while i < len(s):
|
||||
if self.ctoascii(s[i]) < 32:
|
||||
s = s[ :i] + s[i+1: ]
|
||||
i -= 1
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def get_url(self,v,p):
|
||||
vendors = {
|
||||
#CPU产商
|
||||
"INTEL":["Intel"],
|
||||
"AMD":["AMD"],
|
||||
"VIMICRO":["Vimicro"],
|
||||
#显卡产商
|
||||
"ATI":["ATI"],
|
||||
"1002":["ATI"],
|
||||
"SIS":["SIS"],
|
||||
"1039":["SIS"],
|
||||
"NVIDIA":["Nvidia"],
|
||||
"VIA":["VIA"],
|
||||
"XFX":["XFX"],
|
||||
"SUPERGRAPHIC":["Supergraphic"],
|
||||
"JINGJIA":["JJM"],
|
||||
"Wuhan Digital Engineering":["WDE"],
|
||||
#显示器产商
|
||||
"AUO":["AUO"],
|
||||
"AOC":["AOC"],
|
||||
"PHILIPS":["Philips"],
|
||||
"PHL":["Philips"],
|
||||
"LEN":["Lenovo"],
|
||||
"SEC":["SAMSUNG"],
|
||||
#电脑品牌
|
||||
"HASEE":["Hasee"],
|
||||
"FOUNDER":["Founder"],
|
||||
"TONGFANG":["Tongfang"],
|
||||
"TSINGHUA":["Tongfang"],
|
||||
"ACER":["Acer"],
|
||||
"LENOVO":["Lenovo"],
|
||||
"ASUSTEK":["ASUS"],
|
||||
"NEC":["NEC"],
|
||||
"HP":["HP"],
|
||||
"HEWLETT-PACKARD":["HP"],
|
||||
"SAMSUNG":["SAMSUNG"],
|
||||
"TOSHIBA":["TOSHIBA"],
|
||||
"APPLE":["Apple"],
|
||||
"DELL":["DELL"],
|
||||
"FUJITSU":["FUJITSU"],
|
||||
"PANASONIC":["Panasonic"],
|
||||
"SONY":["SONY"],
|
||||
"IBM":["IBM"],
|
||||
#虚拟机
|
||||
"INNOTEK":["VirtualBox"],
|
||||
"VBOX":["VirtualBox"],
|
||||
"VIRTUALBOX":["VirtualBox"],
|
||||
#网卡产商
|
||||
"3COM":["3COM"],
|
||||
"D-LINK":["D-LINK"],
|
||||
"RALINK":["Ralink"],
|
||||
"ATHEROS":["Atheros"],
|
||||
"MARVELL":["Marvell"],
|
||||
"BROADCOM":["Broadcom"],
|
||||
#硬盘产商
|
||||
"EXCELSTOR":["Excelstor"],
|
||||
"HITACHI":["Hitachi"],
|
||||
"MAXTOR":["Maxtor"],
|
||||
"WESTERN":["Western Digital"],
|
||||
"LITEON":["Liteon"],
|
||||
"SEAGATE":["Seagate"],
|
||||
"QUANTUM":["Quantum"],
|
||||
#光驱产商
|
||||
"PLDS":["PLDS"],
|
||||
"PBDS":["PLDS"],
|
||||
"HL-DT-ST":["LG"],
|
||||
"OPTIARC":["SONY"],
|
||||
"TSSTCORP":["TSSTcorp"],
|
||||
"PIONEER":["Pioneer"],
|
||||
"MATSHITA":["Panasonic"],
|
||||
#声卡产商
|
||||
"REALTEK":["Realtek"],
|
||||
"CREATIVE":["Creative"],
|
||||
"LOONGSON":["Loongson"],
|
||||
"HISILICON":["HiSilicon"],
|
||||
#摄像头
|
||||
"SONIX":["Sonix"],
|
||||
"ETRON":["Etron"],
|
||||
"AVEO":["Aveo"],
|
||||
"SYNTEK":["Syntek"],
|
||||
"EMPIA":["Empia"],
|
||||
"CHICONY":["Chicony"],
|
||||
"OMNIVISION":["OmniVision"],
|
||||
#鼠标产商
|
||||
"LOGITECH":["Logitech"],
|
||||
"SUNPLUS":["Sunplus"],
|
||||
"PRIMAX":["Primax"],
|
||||
"PIXART":["Pixart"],
|
||||
"TRUST":["Trust"],
|
||||
"1BCF":["Rapoo"],
|
||||
"AVAGO":["Avago"],
|
||||
"MICROSOFT":["Microsoft"],
|
||||
#键盘产商
|
||||
"RAPOO":["Rapoo"],
|
||||
#主板产商
|
||||
"GIGABYTE":["Gigabyte"],
|
||||
"BIOSTAR":["Biostar"],
|
||||
"COLORFUL":["Colorful"],
|
||||
"YESTON":["Yeston"],
|
||||
#指纹识别
|
||||
"UPEK":["Authentec"],
|
||||
"AUTHENTEC":["Authentec"],
|
||||
#闪存产商
|
||||
"KINGSTON":["Kingston"],
|
||||
"KINGMAX":["Kingmax"],
|
||||
"KINGBOX":["Kingbox"],
|
||||
"HYNIX":["Hynix"],
|
||||
"HYUNDAI":["Hynix"],
|
||||
"MICRON":["Micron"],
|
||||
"06C1":["Asint"],
|
||||
"ADATA":["ADATA"],
|
||||
"ZTE":["ZTE"],
|
||||
"EAGET":["Eaget"],
|
||||
"TEXAS":["Texas Instruments"],
|
||||
"MOTOROLA":["Motorola"],
|
||||
#电源产商
|
||||
"SMP":["SMP"],
|
||||
"SIMPLO":["SMP"],
|
||||
#BIOS产商
|
||||
"AMERICAN":["AMI"],
|
||||
"AWARD":["Phoenix"],
|
||||
"PHOENIX":["Phoenix"]
|
||||
}
|
||||
tmp = v.split(" ")[0]
|
||||
tmp = re.findall("([a-zA-Z0-9-]+)", tmp)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else :
|
||||
k = p.split(" ")[0]
|
||||
url = vendors.get(k.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else:
|
||||
tmp = p.split(" ")[0]
|
||||
url = vendors.get(tmp.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("JingJia", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Loongson", p, flags=re.IGNORECASE)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("Wuhan Digital Engineering", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("ATI", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("ATI", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
return v
|
||||
|
||||
def read_os_name(self):
|
||||
platValue = platform.platform()
|
||||
if os.path.exists("/etc/ubuntukylin-release"):
|
||||
with open("/etc/ubuntukylin-release", "r") as fsys:
|
||||
for line in fsys:
|
||||
if line.startswith("DISTRIB_DESCRIPTION"):
|
||||
tmp = line
|
||||
break
|
||||
# kobe: remove '"' and '\n'
|
||||
front = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
platValue = front
|
||||
elif os.path.exists("/etc/os-release"):
|
||||
tmp = tmp1 = ""
|
||||
with open("/etc/os-release", "r") as fsys:
|
||||
for line in fsys:
|
||||
if line.startswith("NAME"):
|
||||
tmp = line
|
||||
if line.startswith("PRETTY_NAME"):
|
||||
tmp1 = line
|
||||
# 跳出循环规则调整
|
||||
if tmp != "" and tmp1 != "":
|
||||
break
|
||||
# kobe: remove '"' and '\n'
|
||||
front = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
front1 = tmp1.split('=')[1].replace('"', '').replace('\n', '')
|
||||
|
||||
if front == "Kylin":
|
||||
platValue = front
|
||||
else:
|
||||
platValue = front1
|
||||
|
||||
if front == "Kylin" or front == "YHKylin":
|
||||
with open("/etc/lsb-release", "r") as fp:
|
||||
for line in fp:
|
||||
if line.startswith("DISTRIB_VERSION_TYPE"):
|
||||
tmp = line
|
||||
# kobe: remove '"' and '\n'
|
||||
id = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
if id == "community":
|
||||
platValue = "YHKylin community"
|
||||
else:
|
||||
platValue = front1
|
||||
break
|
||||
else:
|
||||
community = ""
|
||||
id = ""
|
||||
with open("/etc/lsb-release", "r") as fp:
|
||||
for line in fp:
|
||||
if line.startswith("DISTRIB_ID"):#if line.startswith("DISTRIB_DESCRIPTION"):
|
||||
tmp = line
|
||||
# kobe: remove '"' and '\n'
|
||||
id = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
elif line.startswith("DISTRIB_VERSION_TYPE"):
|
||||
tmp = line
|
||||
# kobe: remove '"' and '\n'
|
||||
community = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
elif line.startswith("DISTRIB_DESCRIPTION"):
|
||||
tmp = line
|
||||
# kobe: remove '"' and '\n'
|
||||
community1 = tmp.split('=')[1].replace('"', '').replace('\n', '')
|
||||
# break
|
||||
if id == "Kylin":
|
||||
platValue = id
|
||||
else:
|
||||
platValue = community1
|
||||
|
||||
if id == "Kylin" or id == "YHKylin":
|
||||
if community == "community":
|
||||
platValue = "YHKylin community"
|
||||
else:
|
||||
platValue = community1
|
||||
|
||||
return platValue
|
||||
|
||||
def getOutline(self):
|
||||
summary = {}
|
||||
sysBoardInfo = SystemBoard()
|
||||
sysInfo = sysBoardInfo.getSystemInfo()
|
||||
ComVendor,ComProduct,ComVersion,ComSerial, ComOSName = '','','','',''
|
||||
if System_Manufacturer in sysInfo and sysInfo[System_Manufacturer] != "XXXX":
|
||||
ComVendor = sysInfo[System_Manufacturer]
|
||||
else :
|
||||
ComVendor = "Wrong info from firmware"
|
||||
|
||||
if System_Product in sysInfo and sysInfo[System_Product] != "XXXX":
|
||||
ComProduct = sysInfo[System_Product]
|
||||
else :
|
||||
ComProduct = "Wrong info from firmware"
|
||||
|
||||
if System_Version in sysInfo and sysInfo[System_Version] != "XXXX":
|
||||
ComVersion = sysInfo[System_Version]
|
||||
else :
|
||||
ComVersion = "Wrong info from firmware"
|
||||
|
||||
if System_SerialNumber in sysInfo and sysInfo[System_SerialNumber] != "XXXX":
|
||||
ComSerial = sysInfo[System_SerialNumber]
|
||||
else :
|
||||
ComSerial = "Wrong info from firmware"
|
||||
ComVendor = self.get_url(ComVendor,ComProduct)
|
||||
|
||||
ComVendor,ComProduct,ComVersion,ComSerial = self.strip(ComVendor),self.strip(ComProduct),self.strip(ComVersion),self.strip(ComSerial)
|
||||
|
||||
with open('/proc/uptime') as f:
|
||||
for line in f:
|
||||
string = line.split('.')[0]
|
||||
if string.isdigit() :
|
||||
seconds = int(string)
|
||||
else :
|
||||
seconds = 0
|
||||
minutes = seconds / 60
|
||||
uptime = str(minutes)
|
||||
|
||||
ComOSName = self.osname
|
||||
|
||||
summary[MI_MANUFACTURER] = ComVendor
|
||||
summary[MI_MACHINEMODEL] = ComProduct
|
||||
summary[MI_SERIALNUM] = ComSerial
|
||||
summary[MI_VERSION] = ComVersion
|
||||
summary[MI_SYSTEMBITS] = platform.architecture()[0]
|
||||
summary[MI_KERNELARCH] = platform.machine()
|
||||
summary[MI_KERNELVERSION] = platform.release()
|
||||
summary[MI_HOSTNAME] = platform.node()
|
||||
summary[MI_OSVERSION] = ComOSName
|
||||
summary[MI_OSTYPES] = platform.system()
|
||||
summary[MI_RUNINGTIME] = uptime
|
||||
|
||||
baseBoardInfo = sysBoardInfo.getBaseBoardInfo()
|
||||
customedType = 0 ## 0 通用,1 联想 主板名称:
|
||||
if Board_Manufacturer in baseBoardInfo and "lenovo" in baseBoardInfo[Board_Manufacturer].lower() \
|
||||
and Board_Product in baseBoardInfo and ("FD2000ZX200MB1" in baseBoardInfo[Board_Product]) :
|
||||
customedType = 1
|
||||
processorInfo = DetailInfo()
|
||||
summary[MI_PROCESSOR] = processorInfo.getOutline()
|
||||
memInfo = MemoryInfo(self.cmdTool)
|
||||
summary[MI_MEMORY] = memInfo.getOutline(customedType)
|
||||
motherBoardInfo = SystemBoard()
|
||||
summary[MI_MAINBOARD] = motherBoardInfo.getOutline()
|
||||
harddiskInfo = KAHarddiskInfo(self.cmdTool)
|
||||
summary[MI_HARDDISK] = harddiskInfo.getOutline(customedType)
|
||||
graphicsCardInfo = KAGraphicsCardInfo(self.cmdTool)
|
||||
summary[MI_GRAPHICSCARD] = graphicsCardInfo.getOutline(customedType)
|
||||
monitorInfo = KAMonitor()
|
||||
summary[MI_MONITOR] = monitorInfo.getOutline()
|
||||
networkInfo = NetworkAdaptor(self.cmdTool)
|
||||
summary[MI_NETWORKCARD] = networkInfo.getOutline()
|
||||
soundInfo = AudioAdaptor(self.cmdTool)
|
||||
tempSoundInfo = soundInfo.getOutline()
|
||||
if len(tempSoundInfo) > 0 :
|
||||
summary[MI_SOUNDCARD] = tempSoundInfo
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = KAMachineInfo(cmdTool)
|
||||
pprint(cc.getOutline())
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import math
|
||||
import glob
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
class KAMonitor() :
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getMonitorsInfo(self) :
|
||||
infoList = {"list":[]}
|
||||
xrandrDat = ""
|
||||
if os.path.exists("/tmp/youker-assistant-monitorinfo.dat"):
|
||||
status, xrandrDat = subprocess.getstatusoutput('cat /tmp/youker-assistant-monitorinfo.dat')
|
||||
value = re.findall("(.*) connected", xrandrDat)
|
||||
for monitor in value :
|
||||
p = re.compile(r'%s connected' % monitor)
|
||||
for m in p.finditer(xrandrDat):
|
||||
monitorOne = {}
|
||||
mnManufacturer,mnName,mnSize,mnRatio,mnResolution,mnMaxResolution,mnIsMain,mnGamma,mnInterface, \
|
||||
mnModel,mnVisibleArea,mnYear,mnWeek,mnSerial = "","","","","","","","","","","","","",""
|
||||
localinfo = xrandrDat.split("%s connected" % monitor)[1].split("connected")[0]
|
||||
mnInterface = monitor
|
||||
if "primary" in localinfo :
|
||||
mnIsMain = "1"
|
||||
else :
|
||||
mnIsMain = "0"
|
||||
curResolution = re.findall("\s*(\d+)x(\d+)\+", localinfo)
|
||||
if curResolution :
|
||||
curResolutionWidth = int(curResolution[0][0])
|
||||
curResolutionHeight = int(curResolution[0][1])
|
||||
mnResolution = str(curResolutionWidth)+"X"+str(curResolutionHeight)
|
||||
if curResolutionHeight > 0 :
|
||||
ratio = int(curResolutionWidth*100/curResolutionHeight)
|
||||
if ratio == 125 : #5:4
|
||||
mnRatio = "5:4"
|
||||
elif ratio == 133 : #4:3
|
||||
mnRatio = "4:3"
|
||||
elif ratio == 160 : #16:10
|
||||
mnRatio = "16:10"
|
||||
elif ratio == 177 : #16:9
|
||||
mnRatio = "16:9"
|
||||
|
||||
result = re.findall('EDID: \s*(\w*)\s*(\w*)\s*(\w*)\s*\s*(\w*)\s*\s*(\w*)\s*\s*(\w*)\s*\s*(\w*)\s*\s*(\w*)\s*', localinfo)
|
||||
if result :
|
||||
with open("/tmp/edid.dat", "w") as fp:
|
||||
for edidinfoline in result[0] :
|
||||
fp.write(edidinfoline)
|
||||
# 1920x1080 59.93*+
|
||||
result = re.findall('\s*(\d*)x(\d*)\s\s\s', localinfo)
|
||||
if result:
|
||||
nMaxRes = 0
|
||||
for item in result :
|
||||
if item[0].isdigit() and item[1].isdigit() :
|
||||
tempRes = int(item[0])*int(item[1])
|
||||
if tempRes > nMaxRes :
|
||||
nMaxRes = tempRes
|
||||
mnMaxResolution = (item[0] + "X" + item[1])
|
||||
|
||||
if os.path.exists("/tmp/edid.dat"):
|
||||
status, ediddecret = subprocess.getstatusoutput('/usr/bin/edid-decode /tmp/edid.dat')
|
||||
#Display Product Name: LEN T2224rbA
|
||||
#Manufacturer: LEN Model 24810 Serial Number 16843009
|
||||
result_bak = re.findall("Manufacturer:\s*(\w*)\s*Model\s*(\w*)", ediddecret)
|
||||
result = re.findall('Display Product Name:\s*(.*)', ediddecret)
|
||||
if result and len(result) > 0 and len(result[0]) > 0 : ### 笔记本没有Monitor name
|
||||
mnName = result[0].strip()
|
||||
if result_bak :
|
||||
mnManufacturer = result_bak[0][0]
|
||||
if len(mnName) == 0 :
|
||||
if len(result_bak[0]) >= 2 :
|
||||
mnName = result_bak[0][0]+" "+result_bak[0][1]
|
||||
else :
|
||||
mnName = result_bak[0][0]
|
||||
#Made in week 26 of 2020
|
||||
result = re.findall("Made in week\s*(\d*)\s*of\s*(\d*)", ediddecret)
|
||||
if result:
|
||||
mnYear = result[0][1]
|
||||
mnWeek = result[0][0]
|
||||
|
||||
#Alphanumeric Data String: BOE CQ
|
||||
#Alphanumeric Data String: NE140FHM-N61
|
||||
result = re.findall("Alphanumeric Data String:\s*(\S*)", ediddecret)
|
||||
if result and len(result) > 0:
|
||||
if len(result[0]) > 0 :
|
||||
mnManufacturer = result[0]
|
||||
if len(result) >= 2 and len(result[1]) > 0 :
|
||||
mnName = result[1]
|
||||
|
||||
#Maximum image size: 48 cm x 27 cm
|
||||
result = re.findall("Maximum image size:\s*(\d*)\s*cm\s*x\s*(\d*)\s*cm", ediddecret)
|
||||
result2 = re.findall("Detailed mode: Clock (\d*\.\d*) MHz,\s*(\d*)\s*mm\s*x\s*(\d*)\s*mm", ediddecret)
|
||||
isTN133A2 = Judgment_TN133A2()
|
||||
if result2:
|
||||
mx = float(result2[0][1]); my = float(result2[0][2])
|
||||
md = math.sqrt(mx**2 + my**2)/25.4
|
||||
mnVisibleArea = (str(mx) + " X " + str(my) + " cm")
|
||||
# 熊猫华星笔记本屏幕尺寸
|
||||
if md > 13 and md <= 14 and len(mnName) > 0 and True != isTN133A2:
|
||||
md = 14
|
||||
mnSize = str("%.1f" %md)
|
||||
elif result:
|
||||
mx = float(result[0][0]); my = float(result[0][1])
|
||||
md = math.sqrt(mx**2 + my**2)/2.54
|
||||
mnVisibleArea = (str(mx) + " X " + str(my) + " cm")
|
||||
# 熊猫华星笔记本屏幕尺寸
|
||||
if md > 13 and md <= 14 and len(mnName) > 0 and True != isTN133A2:
|
||||
md = 14
|
||||
mnSize = str("%.1f" %md)
|
||||
|
||||
#Gamma: 2.20
|
||||
result = re.findall("Gamma:\s*(\S*)", ediddecret)
|
||||
if result:
|
||||
mnGamma = result[0]
|
||||
|
||||
#Display Product Serial Number: U1610C5W
|
||||
result = re.findall("Display Product Serial Number:\s*(\S*)", ediddecret)
|
||||
if result:
|
||||
mnSerial = result[0]
|
||||
|
||||
#greatwall
|
||||
if len(mnName) > 0 and "24AL60" == mnName :
|
||||
mnSize = "23.8"
|
||||
|
||||
#X100
|
||||
if len(mnName) > 0 and "LM133LF-8L02" == mnName :
|
||||
mnSize = "13.3"
|
||||
|
||||
if len(mnManufacturer) > 0 :
|
||||
monitorOne[MNI_MANUFACTURER] = mnManufacturer
|
||||
if len(mnName) > 0 :
|
||||
monitorOne[MNI_NAME] = mnName
|
||||
if len(mnSize) > 0 :
|
||||
monitorOne[MNI_SIZE] = mnSize
|
||||
if len(mnRatio) > 0 :
|
||||
monitorOne[MNI_RATIO] = mnRatio
|
||||
if len(mnResolution) > 0 :
|
||||
monitorOne[MNI_RESOLUTION] = mnResolution
|
||||
if len(mnMaxResolution) > 0 :
|
||||
monitorOne[MNI_MAXAVARES] = mnMaxResolution
|
||||
if len(mnIsMain) > 0 :
|
||||
monitorOne[MNI_ISMAIN] = mnIsMain
|
||||
if len(mnGamma) > 0 :
|
||||
monitorOne[MNI_GAMMA] = mnGamma
|
||||
if len(mnInterface) > 0 :
|
||||
monitorOne[MNI_INTERFACE] = mnInterface
|
||||
if len(mnModel) > 0 :
|
||||
monitorOne[MNI_MODEL] = mnModel
|
||||
if len(mnVisibleArea) > 0 :
|
||||
monitorOne[MNI_VISIBLEAREA] = mnVisibleArea
|
||||
if len(mnYear) > 0 :
|
||||
monitorOne[MNI_YEAR] = mnYear
|
||||
if len(mnWeek) > 0 :
|
||||
monitorOne[MNI_WEEK] = mnWeek
|
||||
if len(mnSerial) > 0 :
|
||||
monitorOne[MNI_SERIALNUM] = mnSerial
|
||||
|
||||
if len(monitorOne) > 0 :
|
||||
infoList["list"].append(monitorOne)
|
||||
|
||||
if Judgment_HW990():
|
||||
for i in range(len(infoList["list"])-1, -1, -1):
|
||||
if MNI_MANUFACTURER not in infoList["list"][i] :
|
||||
infoList["list"].pop(i)
|
||||
|
||||
if os.path.exists("/sys/class/drm"):
|
||||
edid_files = glob.glob("/sys/class/drm/*/edid")
|
||||
for edid_file in edid_files:
|
||||
if edid_file.find("card0-eDP-1") != -1 :
|
||||
monitorOne = {}
|
||||
monitorOne[MNI_SIZE] = "14"
|
||||
monitorOne[MNI_MAXAVARES] = "2160X1440"
|
||||
monitorOne[MNI_MANUFACTURER] = "LCD"
|
||||
monitorOne[MNI_INTERFACE] = "eDP"
|
||||
infoList["list"].append(monitorOne)
|
||||
|
||||
if "list" in infoList and len(infoList["list"]) == 1 :
|
||||
infoList["list"][0][MNI_ISMAIN] = "1"
|
||||
|
||||
return json.dumps(infoList)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getMonitorsInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if MNI_NAME in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[MNI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[MNI_NAME]
|
||||
if MNI_SIZE in info :
|
||||
outLine += "("+info[MNI_SIZE]+")"
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = KAMonitor()
|
||||
pprint(cc.getMonitorsInfo())
|
||||
#pprint(cc.getOutline())
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
class KAMouseInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getMouseInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
hwinfoList = self.cmdTool.loadInfoFromHwinfo("--mouse")["list"]
|
||||
for mapInfo in hwinfoList :
|
||||
if len(mapInfo) == 0 :
|
||||
continue
|
||||
msOne = {}
|
||||
msName,msManufacturer,msModel,msInterface,msDriver,msType = "","","","","",""
|
||||
##名称
|
||||
if "Device" in mapInfo :
|
||||
msDevice = mapInfo["Device"].split("\"")
|
||||
if len(msDevice) > 1 :
|
||||
msName = msDevice[1]
|
||||
else :
|
||||
msName = mapInfo["Device"]
|
||||
|
||||
##类型
|
||||
if "Hardware Class" in mapInfo :
|
||||
msType = mapInfo["Hardware Class"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
msVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(msVendor) > 1 :
|
||||
msManufacturer = msVendor[1]
|
||||
else :
|
||||
msManufacturer = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
msVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(msVendor) > 1 :
|
||||
msManufacturer = msVendor[1]
|
||||
else :
|
||||
msManufacturer = mapInfo["SubVendor"]
|
||||
|
||||
##接口
|
||||
if "Hotplug" in mapInfo :
|
||||
msInterface = mapInfo["Hotplug"]
|
||||
|
||||
##型号
|
||||
if "Model" in mapInfo :
|
||||
msModel = mapInfo["Model"].strip("\"")
|
||||
if "bluetooth" in msModel :
|
||||
msInterface = "BLUETOOTH"
|
||||
|
||||
##驱动
|
||||
if "Driver" in mapInfo :
|
||||
msDriver = mapInfo["Driver"].strip("\"")
|
||||
|
||||
if len(msName) > 0 :
|
||||
msOne[MSI_NAME] = msName
|
||||
if len(msType) > 0 :
|
||||
msOne[MSI_DEVTYPE] = msType
|
||||
if len(msManufacturer) > 0 :
|
||||
msOne[MSI_MANUFACTURER] = msManufacturer
|
||||
if len(msInterface) > 0 :
|
||||
msOne[MSI_INTERFACE] = msInterface
|
||||
if len(msModel) > 0 :
|
||||
msOne[MSI_DEVMODEL] = msModel
|
||||
if len(msDriver) > 0 :
|
||||
msOne[MSI_DRIVER] = msDriver
|
||||
if len(msOne) > 0 :
|
||||
summary["list"].append(msOne)
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getMouseInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if MSI_NAME in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[MSI_NAME]
|
||||
else :
|
||||
outLine += " / " + info[MSI_NAME]
|
||||
if MSI_DEVMODEL in info :
|
||||
outLine += "("+info[MSI_DEVMODEL]+")"
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cc = KAMouseInfo(cmdTool)
|
||||
pprint(cc.getMouseInfo())
|
||||
#pprint(cc.getOutline())
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
import dbus.service
|
||||
|
||||
KA_POLICYKIT_ACTION = "com.kylin.assistant.systemdaemon.action"
|
||||
|
||||
class AccessDeniedException(dbus.DBusException):
|
||||
'''This exception is raised when some operation is not permitted.'''
|
||||
|
||||
_dbus_error_name = 'com.kylin.assistant.systemdaemon.AccessDeniedException'
|
||||
|
||||
|
||||
class PolicyKitService(dbus.service.Object):
|
||||
'''A D-BUS service that uses PolicyKit for authorization.'''
|
||||
|
||||
def _check_permission(self, sender, action):
|
||||
if not sender: raise ValueError('sender == None')
|
||||
kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
|
||||
kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
|
||||
(granted, _, details) = kit.CheckAuthorization(
|
||||
('system-bus-name', {'name': sender}),
|
||||
action, {}, dbus.UInt32(1), '', timeout=600)
|
||||
return granted
|
|
@ -0,0 +1,269 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
|
||||
from utils import *
|
||||
|
||||
CPUINFO = "/proc/cpuinfo"
|
||||
|
||||
class DetailInfo:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getProcessorInfo(self):
|
||||
|
||||
info = {Pro_Manufacturer: "",
|
||||
Pro_Product: "",
|
||||
Pro_Architecture: "",
|
||||
Pro_Frequency: "",
|
||||
Pro_Frequency_Max: "",
|
||||
Pro_Threads: "",
|
||||
Pro_Family: "",
|
||||
Pro_Model: "",
|
||||
Pro_Stepping: "",
|
||||
Pro_L1dCache: "",
|
||||
Pro_L1iCache: "",
|
||||
Pro_L2Cache: "",
|
||||
Pro_L3Cache: "",
|
||||
Pro_Cores: ""}
|
||||
|
||||
pipe = subprocess.Popen('lscpu', env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
socket = ""
|
||||
corePerSocket = ""
|
||||
thread = ""
|
||||
|
||||
for l in output:
|
||||
line = bytes.decode(l.strip(),"utf-8","ignore")
|
||||
|
||||
##名称
|
||||
if line.startswith("Model name:"):
|
||||
info[Pro_Product] = line.split(":", 1)[1].strip() if info[Pro_Product] == "" else ""
|
||||
|
||||
##架构
|
||||
if line.startswith("Architecture:"):
|
||||
info[Pro_Architecture] = line.split(":", 1)[1].strip() if info[Pro_Architecture] == "" else ""
|
||||
|
||||
##最大频率
|
||||
if line.startswith("CPU max MHz:"):
|
||||
value = line.split(":", 1)[1].strip()
|
||||
value = value.split(".")[0]
|
||||
if value.isdigit() :
|
||||
info[Pro_Frequency_Max] = str(int(float(value))) + " MHz" if info[Pro_Frequency_Max] == "" else ""
|
||||
|
||||
##线程数
|
||||
if line.startswith("Thread(s) per core:"):
|
||||
info[Pro_Threads] = line.split(":", 1)[1].strip() if info[Pro_Threads] == "" else ""
|
||||
|
||||
##型号
|
||||
if line.startswith("Model:"):
|
||||
info[Pro_Model] = line.split(":", 1)[1].strip() if info[Pro_Model] == "" else ""
|
||||
|
||||
##步进
|
||||
if line.startswith("Stepping:"):
|
||||
info[Pro_Stepping] = line.split(":", 1)[1].strip() if info[Pro_Stepping] == "" else ""
|
||||
|
||||
##L1 数据缓存
|
||||
if line.startswith("L1d cache:"):
|
||||
info[Pro_L1dCache] = line.split(":", 1)[1].strip() if info[Pro_L1dCache] == "" else ""
|
||||
|
||||
##L1 指令缓存
|
||||
if line.startswith("L1i cache:"):
|
||||
info[Pro_L1iCache] = line.split(":", 1)[1].strip() if info[Pro_L1iCache] == "" else ""
|
||||
|
||||
##L2 缓存
|
||||
if line.startswith("L2 cache:"):
|
||||
info[Pro_L2Cache] = line.split(":", 1)[1].strip() if info[Pro_L2Cache] == "" else ""
|
||||
|
||||
##L3 缓存
|
||||
if line.startswith("L3 cache:"):
|
||||
info[Pro_L3Cache] = line.split(":", 1)[1].strip() if info[Pro_L3Cache] == "" else ""
|
||||
|
||||
##L3 缓存
|
||||
if line.startswith("Flags:"):
|
||||
flagsInfo = line.split(":", 1)[1].strip()
|
||||
flagsList = flagsInfo.split(" ")
|
||||
validSet = ["MMX", "SSE", "SSE2", "SSE3", "3D Now", "SSE4", "SSSE3", "SSE4_1", "SSE4_2", "AMD64", "EM64T"]
|
||||
extraInstructSet = []
|
||||
for flag in flagsList :
|
||||
for valid in validSet:
|
||||
if valid.lower() == flag.lower() :
|
||||
extraInstructSet.append(valid)
|
||||
if len(extraInstructSet) > 0 :
|
||||
info[Pro_Ext_Instruction_Set] = str(extraInstructSet).strip("[").strip("]").replace(",", "").replace("'","")
|
||||
|
||||
##核数
|
||||
if line.startswith("CPU(s):"):
|
||||
info[Pro_Cores] = line.split(":", 1)[1].strip() if info[Pro_Cores] == "" else ""
|
||||
|
||||
##核数
|
||||
if line.startswith("Socket(s):"):
|
||||
socket = line.split(":", 1)[1].strip()
|
||||
if line.startswith("Core(s) per socket:"):
|
||||
corePerSocket = line.split(":", 1)[1].strip()
|
||||
if line.startswith("Thread(s) per core:"):
|
||||
thread = line.split(":", 1)[1].strip()
|
||||
|
||||
if socket != "" and corePerSocket != "" and thread != "" and info[Pro_Cores] != "" and \
|
||||
socket.isdigit() and corePerSocket.isdigit() and thread.isdigit() and info[Pro_Cores].isdigit() :
|
||||
if(int(info[Pro_Cores]) == int(socket)*int(corePerSocket)*int(thread)):
|
||||
info[Pro_Cores_Online] = info[Pro_Cores] = str(int(socket)*int(corePerSocket))
|
||||
else:
|
||||
info[Pro_Cores_Online] = info[Pro_Cores] = str(int(info[Pro_Cores]))
|
||||
|
||||
args = ["dmidecode", "-t", "processor"]
|
||||
pipe2 = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
output2 = pipe2.stdout.readlines()
|
||||
|
||||
for l in output2:
|
||||
line = bytes.decode(l.strip(),"utf-8","ignore")
|
||||
|
||||
##制造商
|
||||
if line.startswith("Manufacturer:"):
|
||||
info[Pro_Manufacturer] = line.split(":", 1)[1].strip() if info[Pro_Manufacturer] == "" else ""
|
||||
|
||||
if Pro_Product in info :
|
||||
cpuType = info[Pro_Product].lower()
|
||||
if cpuType.find('phytium') >= 0:#Phytium
|
||||
info[Pro_Manufacturer] = 'Phytium'
|
||||
elif cpuType.find('huawei') >= 0:#KunPeng
|
||||
info[Pro_Manufacturer] = 'Huawei'
|
||||
elif cpuType.find('hygon') >= 0:#Hygon
|
||||
info[Pro_Manufacturer] = 'Hygon'
|
||||
elif cpuType.find('zhaoxin') >= 0:#ZHAOXIN
|
||||
info[Pro_Manufacturer] = 'Zhaoxin'
|
||||
elif cpuType.find('loongson') >= 0:#Loongson
|
||||
info[Pro_Manufacturer] = 'Loongson'
|
||||
elif cpuType.find('intel') >= 0:#Loongson
|
||||
info[Pro_Manufacturer] = 'Intel'
|
||||
elif cpuType.find('D2000') >= 0:
|
||||
info[Pro_Manufacturer] = 'Phytium'
|
||||
elif cpuType.find('kirin') >= 0 or cpuType.find('pangu') >= 0:# PanguV lscpu output has no 'huawei'
|
||||
info[Pro_Manufacturer] = 'Huawei'
|
||||
|
||||
##家族
|
||||
if line.startswith("Family:"):
|
||||
info[Pro_Family] = line.split(":", 1)[1].strip() if info[Pro_Family] == "" else ""
|
||||
|
||||
##最大主频
|
||||
if line.startswith("Max Speed:"):
|
||||
if Pro_Frequency_Max not in info or len(info[Pro_Frequency_Max]) == 0 :
|
||||
info[Pro_Frequency_Max] = line.split(":", 1)[1].strip() if info[Pro_Frequency_Max] == "" else ""
|
||||
|
||||
return json.dumps(info)
|
||||
|
||||
#旧接口 获取cpu信息
|
||||
def get_cpuMHZ_from_cpuinfo(self):
|
||||
with open(CPUINFO,'r') as fb:
|
||||
for line in fb.readlines():
|
||||
if line.startswith("cpu MHz") or line.startswith("CPU MHz"):
|
||||
return line.split(":")[1].split(".")[0].strip() + " MHz"
|
||||
|
||||
# 20200616 trans by hebing
|
||||
def get_cpu(self):
|
||||
cpuType = ''
|
||||
Cpu = {}
|
||||
tmpCpu = {}
|
||||
pipe = subprocess.Popen('lscpu', env={'LANGUAGE':'en:'}, stdout=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
pprint(output)
|
||||
|
||||
for line in output:
|
||||
value = bytes.decode(line,"utf-8","ignore").split(":")
|
||||
tmpCpu.setdefault(value[0], value[1].strip())
|
||||
|
||||
socket = tmpCpu.get("Socket(s)", "")
|
||||
i = tmpCpu.get("Core(s) per socket", "")
|
||||
thread = tmpCpu.get("Thread(s) per core", "")
|
||||
core = tmpCpu.get("CPU(s)", "")
|
||||
if core.isdigit() and socket.isdigit() and i.isdigit() and thread.isdigit() :
|
||||
if(int(core) == int(socket)*int(i)*int(thread)):
|
||||
Cpu['cpu_cores_online'] = Cpu['cpu_cores'] = str(int(socket)*int(i))
|
||||
else:
|
||||
Cpu['cpu_cores_online'] = Cpu['cpu_cores'] = str(int(core))
|
||||
|
||||
|
||||
Cpu['CpuCapacity'] = tmpCpu.get("CPU max MHz", "").split(".")[0] + "MHz" if tmpCpu.get("CPU max MHz", "") else ""
|
||||
Cpu['CpuVersion'] = tmpCpu.get("Model name", "")
|
||||
Cpu['CpuVendor'] = tmpCpu.get("Model name", "phytium")#kobe 2020
|
||||
cpuType = Cpu['CpuVendor'].lower()
|
||||
if cpuType.find('phytium') >= 0:#Phytium
|
||||
Cpu['CpuVendor'] = 'Phytium'
|
||||
elif cpuType.find('huawei') >= 0:#KunPeng
|
||||
Cpu['CpuVendor'] = 'Huawei'
|
||||
elif cpuType.find('hygon') >= 0:#Hygon
|
||||
Cpu['CpuVendor'] = 'Hygon'
|
||||
elif cpuType.find('zhaoxin') >= 0:#ZHAOXIN
|
||||
Cpu['CpuVendor'] = 'Zhaoxin'
|
||||
elif cpuType.find('loongson') >= 0:#Loongson
|
||||
Cpu['CpuVendor'] = 'Loongson'
|
||||
if Cpu['CpuCapacity'] == '':
|
||||
Cpu['CpuCapacity'] = self.get_cpuMHZ_from_cpuinfo()
|
||||
elif cpuType.find('intel') >= 0:#Loongson
|
||||
Cpu['CpuVendor'] = 'Intel'
|
||||
elif cpuType.find('D2000') >= 0:
|
||||
Cpu['CpuVendor'] = 'Phytium'
|
||||
elif cpuType.find('kirin') >= 0:
|
||||
Cpu['CpuVendor'] = 'Huawei'
|
||||
elif cpuType.find('pangu') >= 0:# PanguV lscpu output has no 'huawei'
|
||||
Cpu['CpuVendor'] = 'HUAWEI'
|
||||
#Cpu['CpuSlot'] = tmpCpu.get("Socket(s)", "")
|
||||
Cpu['cpu_siblings'] = tmpCpu.get("Thread(s) per core", "")
|
||||
#Cpu['cpu_cores_online'] = os.sysconf("SC_NPROCESSORS_ONLN")
|
||||
|
||||
return Cpu
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getProcessorInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
procCores = "1"
|
||||
procThreadsPerCore = "1"
|
||||
if Pro_Product in outLineObj and len(outLineObj[Pro_Product]) > 0:
|
||||
outLine += outLineObj[Pro_Product]
|
||||
if Pro_Cores in outLineObj and len(outLineObj[Pro_Cores]) > 0:
|
||||
procCores = outLineObj[Pro_Cores]
|
||||
if Pro_Threads in outLineObj and len(outLineObj[Pro_Threads]) > 0:
|
||||
procThreadsPerCore = outLineObj[Pro_Threads]
|
||||
# 判断是否为panguw
|
||||
if False == Judgment_PANGUW():
|
||||
outLine += "("+procCores+"x"+procThreadsPerCore+")"
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = DetailInfo()
|
||||
pprint(cc.getProcessorInfo())
|
||||
#pprint(cc.getOutline())
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
import os
|
||||
import dbus
|
||||
import signal
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
|
||||
from kahwinfo import *
|
||||
from kacpufm import *
|
||||
from kadevmonitor import *
|
||||
|
||||
DBUSNAME = "com.kylin.assistant.systemdaemon"
|
||||
|
||||
class DemoException(dbus.DBusException):
|
||||
_dbus_error_name = "com.kylin.assistant.systemdaemon.KyasException"
|
||||
|
||||
class TestObject(dbus.service.Object):
|
||||
INTERFACE = "com.example.interface"
|
||||
def __init__(self, system_bus, mainloop):
|
||||
dbus.service.Object.__init__(self, system_bus,
|
||||
"/MyObject")
|
||||
self.mainloop = mainloop
|
||||
|
||||
@dbus.service.method(INTERFACE,
|
||||
in_signature = 's', out_signature = 'as')
|
||||
def HelloWorld(self, hello_message):
|
||||
print(str(hello_message))
|
||||
return ["Hello", "from example-service.py", "with unique name",
|
||||
bus.get_unique_name()]
|
||||
|
||||
@dbus.service.method(INTERFACE,
|
||||
in_signature = '', out_signature = 'ss')
|
||||
def GetTuple(self):
|
||||
return ("Hello Tuple", " from example-service.py")
|
||||
|
||||
@dbus.service.method(INTERFACE,
|
||||
in_signature = '', out_signature = '')
|
||||
def RaiseException(self):
|
||||
raise DemoException("The RaiseException method does what you might "
|
||||
'expect')
|
||||
|
||||
@dbus.service.method(INTERFACE,
|
||||
in_signature = '', out_signature = '')
|
||||
def Exit(self):
|
||||
self.mainloop.quit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.environ["TERM"] = "xterm"
|
||||
os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
|
||||
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
|
||||
mainloop = GLib.MainLoop()
|
||||
|
||||
bus = dbus.SystemBus()
|
||||
name = dbus.service.BusName(DBUSNAME, bus)
|
||||
signal.signal(signal.SIGINT, lambda : mainloop.quit())
|
||||
##obj = TestObject(bus, mainloop)
|
||||
obj = HardwareInfo(bus, mainloop)
|
||||
objCpuFM = KACpuFM(bus, mainloop)
|
||||
objDevMonitor = KADevMonitor(bus, mainloop)
|
||||
|
||||
print("Running kyas_system_service...\n")
|
||||
mainloop.run()
|
||||
print("Ending kyas_system_service...\n")
|
||||
if objDevMonitor.cpuTimer :
|
||||
objDevMonitor.cpuTimer.cancel()
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class KAThread(Thread):
|
||||
|
||||
def __init__(self, func, cbfunc, args):
|
||||
'''
|
||||
:param func: 可调用的对象
|
||||
:param args: 可调用对象的参数
|
||||
'''
|
||||
Thread.__init__(self)
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.cbfunc = cbfunc
|
||||
self.result = ""
|
||||
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
if self.cbfunc :
|
||||
self.cbfunc(1, self.result)
|
||||
|
||||
def getResult(self):
|
||||
return self.result
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
Mem_Manufacturer= "Manufacturer"
|
||||
Mem_BankLocator= "Bank Locator"
|
||||
Mem_Type= "Type"
|
||||
Mem_TypeDetail= "Type Detail"
|
||||
Mem_TotalWidth= "Total Width"
|
||||
Mem_DataWidth= "Data Width"
|
||||
Mem_SerialNumber= "Serial Number"
|
||||
Mem_MinVoltage= "Minimum Voltage"
|
||||
Mem_MaxVoltage= "Maximum Voltage"
|
||||
Mem_ConfVoltage= "Configured Voltage"
|
||||
Mem_Rank= "Rank"
|
||||
Mem_FormFactor= "Form Factor"
|
||||
Mem_Product= "Product"
|
||||
|
||||
|
||||
class MemoryInfo():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def isEmpty(self, strValue) :
|
||||
if len(strValue) == 0 or "NONE" == strValue or "None" == strValue or "NULL" == strValue or "Null" == strValue :
|
||||
return True
|
||||
return False
|
||||
|
||||
def getMemInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
args = ["dmidecode", "-t", "memory"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
index = 0
|
||||
marker1 = False
|
||||
marker2 = False
|
||||
memManufacturer,memSize,memType,memSpeed,memTotalBits,memSlot,memSerialNum, \
|
||||
memDataBits,memConfigSpeed,memPipe,memModel,memArrayHandle, memPartNum = "","",\
|
||||
"","","","","","","","","","",""
|
||||
oneMem = {}
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
|
||||
###开启内存概况信息标志位
|
||||
if line.startswith("Physical Memory Array"):
|
||||
marker1 = True
|
||||
if len(memDataBits) > 0 :
|
||||
oneMem[MMI_DATAWIDTH] = memDataBits
|
||||
if len(memManufacturer) > 0 :
|
||||
oneMem[MMI_MANUFACTURER] = memManufacturer
|
||||
if len(memSize) > 0 :
|
||||
oneMem[MMI_TOTALCAPACITY] = memSize
|
||||
if len(memType) > 0 :
|
||||
oneMem[MMI_TYPE] = memType
|
||||
if len(memSpeed) > 0 :
|
||||
oneMem[MMI_SPEED] = memSpeed
|
||||
if len(memTotalBits) > 0 :
|
||||
oneMem[MMI_BUSWIDTH] = memTotalBits
|
||||
if len(memSlot) > 0 :
|
||||
oneMem[MMI_SLOT] = memSlot
|
||||
if len(memSerialNum) > 0 :
|
||||
oneMem[MMI_SERIALNUM] = memSerialNum
|
||||
if len(memConfigSpeed) > 0 :
|
||||
oneMem[MMI_CONFIGSPEED] = memConfigSpeed
|
||||
if len(memPipe) > 0 :
|
||||
oneMem[MMI_PIPE] = memPipe
|
||||
if len(memModel) > 0 :
|
||||
oneMem[MMI_MODEL] = memModel
|
||||
if len(memArrayHandle) > 0 :
|
||||
oneMem[MMI_ARRAYHANDLE] = memArrayHandle
|
||||
if len(memPartNum) > 0 :
|
||||
oneMem[MMI_PARTNUMBER] = memPartNum
|
||||
if len(oneMem) > 0 :
|
||||
summary["list"].append(oneMem)
|
||||
memManufacturer,memSize,memType,memSpeed,memTotalBits,memSlot,memSerialNum, \
|
||||
memDataBits,memConfigSpeed,memPipe,memModel,memArrayHandle, memPartNum = "","",\
|
||||
"","","","","","","","","","",""
|
||||
oneMem = {}
|
||||
|
||||
###
|
||||
if line.startswith("Memory Device"):
|
||||
marker2 = True
|
||||
if len(memDataBits) > 0 :
|
||||
oneMem[MMI_DATAWIDTH] = memDataBits
|
||||
if len(memManufacturer) > 0 :
|
||||
oneMem[MMI_MANUFACTURER] = memManufacturer
|
||||
if len(memSize) > 0 :
|
||||
oneMem[MMI_TOTALCAPACITY] = memSize
|
||||
if len(memType) > 0 :
|
||||
oneMem[MMI_TYPE] = memType
|
||||
if len(memSpeed) > 0 :
|
||||
oneMem[MMI_SPEED] = memSpeed
|
||||
if len(memTotalBits) > 0 :
|
||||
oneMem[MMI_BUSWIDTH] = memTotalBits
|
||||
if len(memSlot) > 0 :
|
||||
oneMem[MMI_SLOT] = memSlot
|
||||
if len(memSerialNum) > 0 :
|
||||
oneMem[MMI_SERIALNUM] = memSerialNum
|
||||
if len(memConfigSpeed) > 0 :
|
||||
oneMem[MMI_CONFIGSPEED] = memConfigSpeed
|
||||
if len(memPipe) > 0 :
|
||||
oneMem[MMI_PIPE] = memPipe
|
||||
if len(memModel) > 0 :
|
||||
oneMem[MMI_MODEL] = memModel
|
||||
if len(memArrayHandle) > 0 :
|
||||
oneMem[MMI_ARRAYHANDLE] = memArrayHandle
|
||||
if len(memPartNum) > 0 :
|
||||
oneMem[MMI_PARTNUMBER] = memPartNum
|
||||
if len(oneMem) > 0 :
|
||||
summary["list"].append(oneMem)
|
||||
memManufacturer,memSize,memType,memSpeed,memTotalBits,memSlot,memSerialNum, \
|
||||
memDataBits,memConfigSpeed,memPipe,memModel,memArrayHandle, memPartNum = "","",\
|
||||
"","","","","","","","","","",""
|
||||
oneMem = {}
|
||||
|
||||
if line == "":
|
||||
marker1 = False
|
||||
if marker2:
|
||||
index += 1
|
||||
marker2 = False
|
||||
|
||||
###过滤所有非必要信息
|
||||
if not marker1 and not marker2:
|
||||
continue
|
||||
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
values = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
###内存概况信息
|
||||
if marker1:
|
||||
|
||||
##支持内存容量
|
||||
if line.startswith("Maximum Capacity:"):
|
||||
summary["Maximum Capacity"] = values[1]
|
||||
|
||||
##支持内存条数
|
||||
if line.startswith("Number Of Devices:"):
|
||||
summary["Number Of Devices"] = values[1]
|
||||
|
||||
if marker2:
|
||||
##名称
|
||||
if line.startswith("Part Number:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memPartNum = tempValue
|
||||
|
||||
##制造商
|
||||
if line.startswith("Manufacturer:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memManufacturer = tempValue
|
||||
|
||||
##内存通道
|
||||
if line.startswith("Bank Locator:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memPipe = tempValue
|
||||
|
||||
##类型
|
||||
if line.startswith("Type:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memType = tempValue
|
||||
|
||||
##总位宽
|
||||
if line.startswith("Total Width:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memTotalBits = tempValue
|
||||
|
||||
##数据位宽
|
||||
if line.startswith("Data Width:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memDataBits = tempValue
|
||||
|
||||
##序列号
|
||||
if line.startswith("Serial Number:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memSerialNum = tempValue
|
||||
|
||||
# ##最低电压
|
||||
# if line.startswith("Minimum Voltage:"):
|
||||
# summary["Mem Infos"][index][Mem_MinVoltage] = values[1]
|
||||
|
||||
# ##最高电压
|
||||
# if line.startswith("Maximum Voltage:"):
|
||||
# summary["Mem Infos"][index][Mem_MaxVoltage] = values[1]
|
||||
|
||||
# ##配置电压
|
||||
# if line.startswith("Configured Voltage:"):
|
||||
# summary["Mem Infos"][index][Mem_ConfVoltage] = values[1]
|
||||
|
||||
##尺寸型号
|
||||
if line.startswith("Form Factor:"):
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memModel = tempValue
|
||||
|
||||
##位列
|
||||
# if line.startswith("Rank:"):
|
||||
# summary["Mem Infos"][index][Mem_Rank] = values[1]
|
||||
|
||||
##容量
|
||||
if line.startswith("Volatile Size:") :
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memSize = tempValue
|
||||
|
||||
if line.startswith("Speed:") :
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memSpeed = tempValue
|
||||
|
||||
if line.startswith("Configured Memory Speed:") :
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memConfigSpeed = tempValue
|
||||
|
||||
if memManufacturer == "UNILC" and memPartNum == "6478545886" :
|
||||
memSpeed = "2666 MT/s"
|
||||
memConfigSpeed = "2666 MT/s"
|
||||
|
||||
if line.startswith("Locator:") :
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memSlot = tempValue
|
||||
|
||||
if line.startswith("Array Handle:") :
|
||||
if values and len(values) > 1:
|
||||
tempValue = values[1].strip()
|
||||
if not self.isEmpty(tempValue) :
|
||||
memArrayHandle = tempValue
|
||||
if len(memDataBits) > 0 :
|
||||
oneMem[MMI_DATAWIDTH] = memDataBits
|
||||
if len(memManufacturer) > 0 :
|
||||
oneMem[MMI_MANUFACTURER] = memManufacturer
|
||||
if len(memSize) > 0 :
|
||||
oneMem[MMI_TOTALCAPACITY] = memSize
|
||||
if len(memType) > 0 :
|
||||
oneMem[MMI_TYPE] = memType
|
||||
if len(memSpeed) > 0 :
|
||||
oneMem[MMI_SPEED] = memSpeed
|
||||
if len(memTotalBits) > 0 :
|
||||
oneMem[MMI_BUSWIDTH] = memTotalBits
|
||||
if len(memSlot) > 0 :
|
||||
oneMem[MMI_SLOT] = memSlot
|
||||
if len(memSerialNum) > 0 :
|
||||
oneMem[MMI_SERIALNUM] = memSerialNum
|
||||
if len(memConfigSpeed) > 0 :
|
||||
oneMem[MMI_CONFIGSPEED] = memConfigSpeed
|
||||
if len(memPipe) > 0 :
|
||||
oneMem[MMI_PIPE] = memPipe
|
||||
if len(memModel) > 0 :
|
||||
oneMem[MMI_MODEL] = memModel
|
||||
if len(memArrayHandle) > 0 :
|
||||
oneMem[MMI_ARRAYHANDLE] = memArrayHandle
|
||||
if len(memPartNum) > 0 :
|
||||
oneMem[MMI_PARTNUMBER] = memPartNum
|
||||
if len(oneMem) > 0 :
|
||||
summary["list"].append(oneMem)
|
||||
memManufacturer,memSize,memType,memSpeed,memTotalBits,memSlot,memSerialNum, \
|
||||
memDataBits,memConfigSpeed,memPipe,memModel,memArrayHandle, memPartNum = "","",\
|
||||
"","","","","","","","","","",""
|
||||
oneMem = {}
|
||||
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
for mapInfo in self.cmdTool.lshwMemoryList :
|
||||
if "slot" in mapInfo and len(mapInfo["slot"]) > 0 :
|
||||
length = len(summary["list"])
|
||||
if length > 0 :
|
||||
for index in range(length):
|
||||
if MMI_SLOT in summary["list"][index] and summary["list"][index][MMI_SLOT] == mapInfo["slot"]:
|
||||
if "size" in mapInfo and MMI_TOTALCAPACITY not in summary["list"][index]:
|
||||
tempSize = mapInfo["size"]
|
||||
tempSize = tempSize.replace("GiB","GB")
|
||||
if "MiB" in tempSize :
|
||||
tempSize = tempSize.replace("MiB","")
|
||||
if tempSize.isdigit() :
|
||||
size = float(tempSize)/1024.0
|
||||
summary["list"][index][MMI_TOTALCAPACITY] = str(float("%.1f" % size))+"GB"
|
||||
else :
|
||||
summary["list"][index][MMI_TOTALCAPACITY] = tempSize
|
||||
if "vendor" in mapInfo and MMI_MANUFACTURER not in summary["list"][index]:
|
||||
summary["list"][index][MMI_MANUFACTURER] = mapInfo["vendor"]
|
||||
if "product" in mapInfo and MMI_PARTNUMBER not in summary["list"][index]:
|
||||
summary["list"][index][MMI_PARTNUMBER] = mapInfo["product"]
|
||||
if "width" in mapInfo and MMI_DATAWIDTH not in summary["list"][index]:
|
||||
summary["list"][index][MMI_DATAWIDTH] = mapInfo["width"]
|
||||
continue
|
||||
else :
|
||||
memInfo = {}
|
||||
memInfo[MMI_SLOT] = mapInfo["slot"]
|
||||
if "size" in mapInfo :
|
||||
tempSize = mapInfo["size"]
|
||||
tempSize = tempSize.replace("GiB","GB")
|
||||
if "MiB" in tempSize :
|
||||
tempSize = tempSize.replace("MiB","")
|
||||
if tempSize.isdigit() :
|
||||
size = float(tempSize)/1024.0
|
||||
memInfo[MMI_TOTALCAPACITY] = str(float("%.1f" % size))+"GB"
|
||||
else :
|
||||
memInfo[MMI_TOTALCAPACITY] = tempSize
|
||||
if "vendor" in mapInfo :
|
||||
memInfo[MMI_MANUFACTURER] = mapInfo["vendor"]
|
||||
if "product" in mapInfo :
|
||||
memInfo[MMI_PARTNUMBER] = mapInfo["product"]
|
||||
if "width" in mapInfo :
|
||||
memInfo[MMI_DATAWIDTH] = mapInfo["width"]
|
||||
if "description" in mapInfo :
|
||||
memInfo[MMI_MODEL] = mapInfo["description"]
|
||||
if "physical id" in mapInfo :
|
||||
memInfo[MMI_PHYSICALID] = mapInfo["physical id"]
|
||||
summary["list"].append(memInfo)
|
||||
else : ##没有slot
|
||||
if len(summary["list"]) == 0 :
|
||||
memInfo = {}
|
||||
if "slot" in mapInfo :
|
||||
memInfo[MMI_SLOT] = mapInfo["slot"]
|
||||
if "size" in mapInfo :
|
||||
tempSize = mapInfo["size"]
|
||||
tempSize = tempSize.replace("GiB","GB")
|
||||
if "MiB" in tempSize :
|
||||
tempSize = tempSize.replace("MiB","")
|
||||
if tempSize.isdigit() :
|
||||
size = float(tempSize)/1024.0
|
||||
memInfo[MMI_TOTALCAPACITY] = str(float("%.1f" % size))+"GB"
|
||||
else :
|
||||
memInfo[MMI_TOTALCAPACITY] = tempSize
|
||||
if "vendor" in mapInfo :
|
||||
memInfo[MMI_MANUFACTURER] = mapInfo["vendor"]
|
||||
if "product" in mapInfo :
|
||||
memInfo[MMI_PARTNUMBER] = mapInfo["product"]
|
||||
if "width" in mapInfo :
|
||||
memInfo[MMI_DATAWIDTH] = mapInfo["width"]
|
||||
if "description" in mapInfo :
|
||||
memInfo[MMI_MODEL] = mapInfo["description"]
|
||||
if MMI_MANUFACTURER not in memInfo :
|
||||
memInfo[MMI_MANUFACTURER] = mapInfo["description"]
|
||||
if "physical id" in mapInfo :
|
||||
memInfo[MMI_PHYSICALID] = mapInfo["physical id"]
|
||||
summary["list"].append(memInfo)
|
||||
##remove invalid info
|
||||
customedType = Judgment_LENOVO()
|
||||
for infoItem in summary["list"][:] :
|
||||
if MMI_TOTALCAPACITY not in infoItem :
|
||||
summary["list"].remove(infoItem)
|
||||
else:
|
||||
tmpItem = infoItem
|
||||
summary["list"].remove(infoItem)
|
||||
if 1 == customedType :
|
||||
# 转换型号格式
|
||||
tmpDict={}
|
||||
tmpDict["list"] = [tmpItem]
|
||||
tmpItem[MMI_MODEL] = self.exchangeModel(tmpDict)
|
||||
summary["list"].append(tmpItem)
|
||||
else:
|
||||
# 不展示型号tmpDict
|
||||
tmpItem.pop(MMI_MODEL)
|
||||
summary["list"].append(tmpItem)
|
||||
# customedType = Judgment_LENOVO()
|
||||
#
|
||||
# memInfo[MMI_MODEL] = exchangeModel([mapInfo])
|
||||
# else:
|
||||
# infoItem.pop(MMI_MODEL)
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self, customType) :
|
||||
outLine = self.getMemInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if 1 == customType : ## lenovo
|
||||
outLine = self.exchangeModel(outLineObj)
|
||||
else :
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if MMI_TOTALCAPACITY in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[MMI_TOTALCAPACITY]
|
||||
else :
|
||||
outLine += " / " + info[MMI_TOTALCAPACITY]
|
||||
if MMI_MANUFACTURER in info :
|
||||
outLine += " "+info[MMI_MANUFACTURER]
|
||||
if MMI_TYPE in info :
|
||||
outLine += " "+info[MMI_TYPE]
|
||||
if MMI_SPEED in info :
|
||||
outLine += " "+info[MMI_SPEED]
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
#联想定制转换
|
||||
def exchangeModel(self, outLineObj):
|
||||
outLine = ""
|
||||
nIndex = 0
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if MMI_MANUFACTURER in info :
|
||||
memManufacturer = exchangeManufacturer(info[MMI_MANUFACTURER])
|
||||
if nIndex == 0 :
|
||||
outLine += "MEM-"+memManufacturer
|
||||
else :
|
||||
outLine += " / MEM-"+memManufacturer
|
||||
if MMI_TOTALCAPACITY in info :
|
||||
outLine += "-"+info[MMI_TOTALCAPACITY]
|
||||
if MMI_TYPE in info :
|
||||
outLine += "-"+info[MMI_TYPE]+"-UDIMM"
|
||||
nIndex = nIndex + 1
|
||||
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdtool = KACmdTool()
|
||||
cmdtool.loadInfoFromLshw()
|
||||
cc = MemoryInfo(cmdtool)
|
||||
pprint(cc.getMemInfo())
|
||||
# pprint(cc.getOutline(1))
|
||||
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import copy
|
||||
import utils
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
from utils import *
|
||||
|
||||
NetAdaptor_Product= "Product"
|
||||
NetAdaptor_Manufacturer= "Vendor"
|
||||
NetAdaptor_Type= "Description"
|
||||
NetAdaptor_Version= "Version"
|
||||
NetAdaptor_Businfo= "Bus Info"
|
||||
NetAdaptor_Capabilities= "Capabilities"
|
||||
NetAdaptor_Driver= "Driver"
|
||||
NetAdaptor_Logicalname= "Logical Name"
|
||||
NetAdaptor_Serial= "Serial"
|
||||
NetAdaptor_IRQ= "IRQ"
|
||||
NetAdaptor_Memory= "Memory"
|
||||
NetAdaptor_Width= "Width"
|
||||
NetAdaptor_Clock= "Clock"
|
||||
NetAdaptor_Broadcast= "Broadcast"
|
||||
NetAdaptor_Firmware= "Firmware"
|
||||
NetAdaptor_IP= "IP"
|
||||
NetAdaptor_Link= "Link"
|
||||
NetAdaptor_Port= "Port"
|
||||
NetAdaptor_Capacity= "Capacity"
|
||||
NetAdaptor_Physicalid= "Physical ID"
|
||||
NetAdaptor_Size= "Size"
|
||||
NetAdaptor_Multicast= "Multicast"
|
||||
NetAdaptor_Autonegotiation= "Autonegotiation"
|
||||
NetAdaptor_Latency= "Latency"
|
||||
NetAdaptor_Mask= "subnet_mask"
|
||||
NetAdaptor_Txdata= "send_bytes"
|
||||
NetAdaptor_Rxdata= "recv_bytes"
|
||||
NetAdaptor_Mtu= "mtu"
|
||||
|
||||
class NetworkAdaptor():
|
||||
|
||||
def __init__(self, cmdtool):
|
||||
self.cmdTool = cmdtool
|
||||
pass
|
||||
|
||||
def getNetworkAdaptorInfo(self):
|
||||
summary = {"list":[]}
|
||||
|
||||
self.cmdTool.loadInfoFromLshw(False)
|
||||
networkAdaptorList = copy.deepcopy(self.cmdTool.lshwNetworkList)
|
||||
for usbNetwork in self.cmdTool.lshwUsbList :
|
||||
if "capabilities" in usbNetwork and "Bluetooth".lower() not in usbNetwork["capabilities"].lower() and \
|
||||
("Wireless".lower() in usbNetwork["capabilities"].lower() or "Ethernet".lower() in usbNetwork["capabilities"].lower()) :
|
||||
networkAdaptorList.append(usbNetwork)
|
||||
adaptorList = self.cmdTool.loadInfoFromHwinfo("--network")["list"]
|
||||
ifconfigList = self.cmdTool.loadNetworkInfoFromIfconfig()
|
||||
length = len(networkAdaptorList)
|
||||
for i in range(length) :
|
||||
if "bus info" in networkAdaptorList[i] :
|
||||
words = networkAdaptorList[i]["bus info"].split("@")
|
||||
if len(words) != 2 :
|
||||
continue
|
||||
key = words[1].strip()
|
||||
#key = key.replace(".","" in mapInfo
|
||||
for mapInfo in adaptorList :
|
||||
if "SysFS Device Link" in mapInfo :
|
||||
if key not in mapInfo["SysFS Device Link"] :
|
||||
continue
|
||||
networkAdaptorList[i].update(mapInfo)
|
||||
if "logical name" in networkAdaptorList[i] :
|
||||
for mapInfo in ifconfigList :
|
||||
if "NetName" in mapInfo and mapInfo["NetName"] == networkAdaptorList[i]["logical name"]:
|
||||
networkAdaptorList[i].update(mapInfo)
|
||||
break
|
||||
|
||||
|
||||
index = 0
|
||||
for mapInfo in networkAdaptorList :
|
||||
if len(mapInfo) > 0 :
|
||||
## 过滤 ‘dummy’名称网卡
|
||||
if "logical name" in mapInfo and "dummy" in mapInfo["logical name"] :
|
||||
continue
|
||||
summary["list"].append({})
|
||||
##名称
|
||||
if "product" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Product] = mapInfo["product"]
|
||||
|
||||
##制造商
|
||||
if "Vendor" in mapInfo :
|
||||
hwVendor = mapInfo["Vendor"].split("\"")
|
||||
if len(hwVendor) > 1 :
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = hwVendor[1]
|
||||
else :
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = mapInfo["Vendor"]
|
||||
if "SubVendor" in mapInfo :
|
||||
hwVendor = mapInfo["SubVendor"].split("\"")
|
||||
if len(hwVendor) > 1 :
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = hwVendor[1]
|
||||
else :
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = mapInfo["SubVendor"]
|
||||
if "vendor" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = mapInfo["vendor"]
|
||||
|
||||
##类型
|
||||
if "description" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Type] = mapInfo["description"]
|
||||
|
||||
##版本
|
||||
if "version" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Version] = mapInfo["version"]
|
||||
|
||||
##物理地址
|
||||
if "serial" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Serial] = mapInfo["serial"]
|
||||
|
||||
##总线信息
|
||||
if "bus info" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Businfo] = mapInfo["bus info"]
|
||||
|
||||
##功能
|
||||
if "capabilities" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Capabilities] = mapInfo["capabilities"]
|
||||
|
||||
##逻辑名称
|
||||
if "logical name" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Logicalname] = mapInfo["logical name"]
|
||||
|
||||
##速度
|
||||
if "size" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Size] = mapInfo["size"]
|
||||
|
||||
##位宽
|
||||
if "width" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Width] = mapInfo["width"]
|
||||
|
||||
##容量
|
||||
if "capacity" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Capacity] = mapInfo["capacity"]
|
||||
|
||||
##物理ID
|
||||
if "physical id" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Physicalid] = mapInfo["physical id"]
|
||||
|
||||
##时钟频率
|
||||
if "clock" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Clock] = mapInfo["clock"]
|
||||
|
||||
##中断
|
||||
if "irq" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_IRQ] = mapInfo["irq"]
|
||||
|
||||
##内存
|
||||
if "memory" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Memory] = mapInfo["memory"]
|
||||
|
||||
##驱动
|
||||
if "driver" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Driver] = mapInfo["driver"]
|
||||
|
||||
##自动协商
|
||||
if "autonegotiation" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Autonegotiation] = mapInfo["autonegotiation"]
|
||||
|
||||
##广播
|
||||
if "broadcast" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Broadcast] = mapInfo["broadcast"]
|
||||
|
||||
##固件
|
||||
if "firmware" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Firmware] = mapInfo["firmware"]
|
||||
|
||||
##IP
|
||||
if "NetIp" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_IP] = mapInfo["NetIp"]
|
||||
|
||||
##延迟
|
||||
if "latency" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Latency] = mapInfo["latency"]
|
||||
|
||||
##连接
|
||||
if "link" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Link] = mapInfo["link"]
|
||||
|
||||
##组播
|
||||
if "multicast" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Multicast] = mapInfo["multicast"]
|
||||
|
||||
##端口
|
||||
if "port" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Port] = mapInfo["port"]
|
||||
|
||||
##子网掩码
|
||||
if "NetMask" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Mask] = mapInfo["NetMask"]
|
||||
|
||||
##发送数据
|
||||
if "NetTxData" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Txdata] = mapInfo["NetTxData"]
|
||||
|
||||
##接收数据
|
||||
if "NetRxData" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Rxdata] = mapInfo["NetRxData"]
|
||||
|
||||
##MTU
|
||||
if "NetMTU" in mapInfo :
|
||||
summary["list"][index][NetAdaptor_Mtu] = mapInfo["NetMTU"]
|
||||
|
||||
##华为内置网卡做特殊处理(制造商、型号、驱动),规避方案
|
||||
if Judgment_PANGUW() and "Vendor" not in mapInfo and "vendor" not in mapInfo and "product" not in mapInfo and "driver" not in mapInfo:
|
||||
if not os.path.exists("/sys/hisys/wal/bt_wifi_device_info") :
|
||||
break;
|
||||
else:
|
||||
# 获取WiFi的制造商和型号
|
||||
args = ["cat","/sys/hisys/wal/bt_wifi_device_info"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
for i in range(len(output)):
|
||||
if "WiFi" in str(bytes.decode(output[i],"utf-8","ignore")):
|
||||
product = str(bytes.decode(output[i+1],"utf-8","ignore")).split(":")[-1].strip()
|
||||
vendor = str(bytes.decode(output[i+3],"utf-8","ignore")).split(":")[-1].strip()
|
||||
summary["list"][index][NetAdaptor_Product] =product
|
||||
summary["list"][index][NetAdaptor_Manufacturer] = vendor
|
||||
break
|
||||
|
||||
args = ["ls","/sys/module/plat_1105/drivers/","| grep sdio"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
for i in range(len(output)):
|
||||
if "sdio" in str(bytes.decode(output[i],"utf-8","ignore")):
|
||||
driver = str(bytes.decode(output[i],"utf-8","ignore")).split(":")[-1].strip()
|
||||
summary["list"][index][NetAdaptor_Driver] = driver
|
||||
break
|
||||
|
||||
index += 1
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLine = self.getNetworkAdaptorInfo()
|
||||
outLineObj = json.loads(outLine)
|
||||
outLine = ""
|
||||
if len(outLineObj) > 0 and "list" in outLineObj :
|
||||
nIndex = 0
|
||||
for info in outLineObj["list"] :
|
||||
if NetAdaptor_Product in info and len(info[NetAdaptor_Product]) > 0:
|
||||
if nIndex == 0 :
|
||||
outLine += info[NetAdaptor_Product]
|
||||
else :
|
||||
outLine += " / " + info[NetAdaptor_Product]
|
||||
elif NetAdaptor_Type in info :
|
||||
if nIndex == 0 :
|
||||
outLine += info[NetAdaptor_Type]
|
||||
else :
|
||||
outLine += " / " + info[NetAdaptor_Type]
|
||||
nIndex = nIndex + 1
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmdTool = KACmdTool()
|
||||
cmdTool.loadInfoFromLshw()
|
||||
cc = NetworkAdaptor(cmdTool)
|
||||
pprint(cc.getNetworkAdaptorInfo())
|
|
@ -0,0 +1,524 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
### BEGIN LICENSE
|
||||
# Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
#
|
||||
# Authors:
|
||||
# Yang Min yangmin@kylinos.cn
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
### END LICENSE
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
from kajsondef import *
|
||||
from kathread import *
|
||||
|
||||
Board_Product= "Product Name"
|
||||
Board_Manufacturer= "Manufacturer"
|
||||
Board_Version= "Version"
|
||||
Board_Chipset= "Chipset"
|
||||
Board_SMBIOS_Version= "SMBIOS"
|
||||
Board_Serial= "Serial Number"
|
||||
Board_Location= "Location In Chassis"
|
||||
Board_ChassisHandle= "Chassis Handle"
|
||||
Board_Features= "Features"
|
||||
Board_ContainedObjHandles= "Contained Object Handles"
|
||||
Board_Type= "Type"
|
||||
Board_AssetTag= "Asset Tag"
|
||||
|
||||
BIOS_Manufacturer= "Vendor"
|
||||
BIOS_Version= "Version"
|
||||
BIOS_Revision= "BIOS Revision"
|
||||
BIOS_FirmwareRevision= "Firmware Revision"
|
||||
BIOS_RomSize= "ROM Size"
|
||||
BIOS_ReleaseDate= "Release Date"
|
||||
BIOS_InstallableLan= "Installable Languages"
|
||||
BIOS_Address= "Address"
|
||||
BIOS_CurrentInstallableLan= "Currently Installed Language"
|
||||
BIOS_Characteristics= "Characteristics"
|
||||
BIOS_LanguageDescFormat= "Language Description Format"
|
||||
BIOS_RuntimeSize= "Runtime Size"
|
||||
|
||||
|
||||
System_Product= "Product Name"
|
||||
System_Manufacturer= "Manufacturer"
|
||||
System_Version= "Version"
|
||||
System_SKU_Number= "SKU Number"
|
||||
System_UUID= "UUID"
|
||||
System_WakeUpType= "Wake-up Type"
|
||||
System_Family= "Family"
|
||||
System_SerialNumber= "Serial Number"
|
||||
|
||||
|
||||
Chassis_Manufacturer= "Manufacturer"
|
||||
Chassis_Version= "Version"
|
||||
Chassis_OEM_Info= "OEM Information"
|
||||
Chassis_SKU_Number= "SKU Number"
|
||||
Chassis_PowerSupplyState= "Power Supply State"
|
||||
Chassis_ContainedElements= "Contained Elements"
|
||||
Chassis_SerialNumber= "Serial Number"
|
||||
Chassis_BootUpState= "Boot-up State"
|
||||
Chassis_ThermalState= "Thermal State"
|
||||
Chassis_NumberOfPowerCords= "Number Of Power Cords"
|
||||
Chassis_Type= "Type"
|
||||
Chassis_AssetTag= "Asset Tag"
|
||||
Chassis_Height= "Height"
|
||||
|
||||
|
||||
class SystemBoard():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getSystemBoardInfo(self):
|
||||
summary = {"BaseBoard Infos":{}, "BIOS Infos":{}, "System Infos":{}, "Chassis Infos":{}}
|
||||
|
||||
summary["BaseBoard Infos"] = self.getBaseBoardInfo()
|
||||
summary["BIOS Infos"] = self.getBiosInfo()
|
||||
summary["Chassis Infos"] = self.getChassisInfo()
|
||||
summary["System Infos"] = self.getSystemInfo()
|
||||
|
||||
return json.dumps(summary)
|
||||
|
||||
def getSystemInfo(self):
|
||||
systeminfo = {}
|
||||
|
||||
args = ["dmidecode", "-t", "system"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
marker1 = False
|
||||
marker2 = False
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
# pprint(line)
|
||||
|
||||
###开启System信息标志位
|
||||
if line.startswith("System Information"):
|
||||
marker1 = True
|
||||
continue
|
||||
if line.startswith("System Event Log"):
|
||||
marker2 = True
|
||||
continue
|
||||
|
||||
if line == "":
|
||||
marker1 = False
|
||||
marker2 = False
|
||||
|
||||
###过滤所有非必要信息
|
||||
if not marker1 and not marker2:
|
||||
continue
|
||||
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
values = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
###System信息
|
||||
if marker1:
|
||||
##制造商
|
||||
if line.startswith("Manufacturer:"):
|
||||
# 处理特殊字符
|
||||
if 2 < values[1].count('.'):
|
||||
systeminfo[System_Manufacturer] = values[1].replace(".","")
|
||||
# 判断是否为百信辰龙
|
||||
if "" == systeminfo[System_Manufacturer] and b'\tProduct Name: ............221EA\n' in output:
|
||||
systeminfo[System_Manufacturer] = "BaiXin"
|
||||
else:
|
||||
systeminfo[System_Manufacturer] = values[1]
|
||||
pass
|
||||
|
||||
##版本
|
||||
if line.startswith("Version:"):
|
||||
systeminfo[System_Version] = values[1]
|
||||
pass
|
||||
|
||||
##SKU号
|
||||
if line.startswith("SKU Number:"):
|
||||
systeminfo[System_SKU_Number] = values[1]
|
||||
pass
|
||||
|
||||
##UUID
|
||||
if line.startswith("UUID:"):
|
||||
systeminfo[System_UUID] = values[1]
|
||||
pass
|
||||
|
||||
##产品名称
|
||||
if line.startswith("Product Name:"):
|
||||
if 2 < values[1].count('.'):
|
||||
systeminfo[System_Product] = values[1].replace(".","")
|
||||
else:
|
||||
systeminfo[System_Product] = values[1]
|
||||
pass
|
||||
|
||||
##唤醒类型
|
||||
if line.startswith("Wake-up Type:"):
|
||||
systeminfo[System_WakeUpType] = values[1]
|
||||
pass
|
||||
|
||||
##家族
|
||||
if line.startswith("Family:"):
|
||||
systeminfo[System_Family] = values[1]
|
||||
pass
|
||||
|
||||
##序列号
|
||||
if line.startswith("Serial Number:"):
|
||||
systeminfo[System_SerialNumber] = values[1]
|
||||
pass
|
||||
|
||||
return systeminfo
|
||||
|
||||
def getBaseboardChipFamily(slef):
|
||||
chipFamily = ""
|
||||
|
||||
args = ["lspci"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
if len(line) > 0 :
|
||||
pciid = line.split(" ")
|
||||
|
||||
if len(pciid) >= 2 and pciid[1] == "ISA":
|
||||
args1 = ["lspci", "-v", "-s", pciid[0].strip()]
|
||||
pipe1 = subprocess.Popen(args1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output1 = pipe1.stdout.readlines()
|
||||
|
||||
for line1 in [ bytes.decode(l1.strip(),"utf-8","ignore") for l1 in output1]:
|
||||
if "Subsystem" in line1 or "subsystem" in line1:
|
||||
chipsinfo = line1.split(": ");
|
||||
if len(chipsinfo) == 2:
|
||||
chipFamily = chipsinfo[1].strip()
|
||||
break
|
||||
return chipFamily
|
||||
|
||||
def getBiosInfo(self):
|
||||
biosinfo = {}
|
||||
|
||||
args = ["dmidecode", "-t", "bios"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
marker1 = False
|
||||
marker2 = False
|
||||
hasCharacteristics = False
|
||||
recordCharacteristic = []
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
# pprint(line)
|
||||
|
||||
###开启BIOS信息标志位
|
||||
if line.startswith("BIOS Information"):
|
||||
marker1 = True
|
||||
continue
|
||||
if line.startswith("BIOS Language Information"):
|
||||
marker2 = True
|
||||
continue
|
||||
|
||||
if line == "":
|
||||
marker1 = False
|
||||
marker2 = False
|
||||
|
||||
###过滤所有非必要信息
|
||||
if not marker1 and not marker2:
|
||||
continue
|
||||
|
||||
###BIOS信息的特殊处理
|
||||
if hasCharacteristics and ":" not in line:
|
||||
recordCharacteristic.append(line)
|
||||
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
values = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
###BIOS信息
|
||||
if marker1:
|
||||
|
||||
##制造商
|
||||
if line.startswith("Vendor:"):
|
||||
biosinfo[BIOS_Manufacturer] = values[1]
|
||||
|
||||
##版本
|
||||
if line.startswith("Version:"):
|
||||
biosinfo[BIOS_Version] = values[1]
|
||||
|
||||
##BIOS修订版本
|
||||
if line.startswith("BIOS Revision:"):
|
||||
biosinfo[BIOS_Revision] = values[1]
|
||||
|
||||
##固件修订版本
|
||||
if line.startswith("Firmware Revision:"):
|
||||
biosinfo[BIOS_FirmwareRevision] = values[1]
|
||||
|
||||
##ROM大小
|
||||
if line.startswith("ROM Size:"):
|
||||
biosinfo[BIOS_RomSize] = values[1]
|
||||
|
||||
##发布日期
|
||||
if line.startswith("Release Date:"):
|
||||
biosinfo[BIOS_ReleaseDate] = values[1]
|
||||
|
||||
##地址
|
||||
if line.startswith("Address:"):
|
||||
biosinfo[BIOS_Address] = values[1]
|
||||
|
||||
##特性
|
||||
if line.startswith("Characteristics:"):
|
||||
biosinfo[BIOS_Characteristics] = values[1]
|
||||
|
||||
##运行内存大小
|
||||
if line.startswith("Runtime Size:"):
|
||||
biosinfo[BIOS_RuntimeSize] = values[1]
|
||||
|
||||
###BIOS语言信息
|
||||
if marker2:
|
||||
##语言描述格式
|
||||
if line.startswith("Language Description Format:"):
|
||||
biosinfo[BIOS_LanguageDescFormat] = values[1]
|
||||
pass
|
||||
|
||||
##可安装语言数
|
||||
if line.startswith("Installable Languages:"):
|
||||
biosinfo[BIOS_InstallableLan] = values[1]
|
||||
pass
|
||||
|
||||
##当前安装语言
|
||||
if line.startswith("Currently Installed Language:"):
|
||||
biosinfo[BIOS_CurrentInstallableLan] = values[1]
|
||||
pass
|
||||
|
||||
return biosinfo
|
||||
|
||||
def getBaseBoardInfo(self):
|
||||
boardinfo = {}
|
||||
|
||||
args = ["dmidecode", "-t", "baseboard"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
marker1 = False
|
||||
hasFeature = False
|
||||
|
||||
recordFeature = []
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
# pprint(line)
|
||||
|
||||
###开启主板信息标志位
|
||||
if line.startswith("Base Board Information"):
|
||||
marker1 = True
|
||||
continue
|
||||
|
||||
if line == "":
|
||||
marker1 = False
|
||||
|
||||
###过滤所有非必要信息
|
||||
if not marker1:
|
||||
continue
|
||||
|
||||
###主板信息的特殊处理
|
||||
if hasFeature and ":" not in line:
|
||||
recordFeature.append(line)
|
||||
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
values = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
###主板信息
|
||||
if marker1:
|
||||
|
||||
##制造商
|
||||
if line.startswith("Manufacturer:"):
|
||||
boardinfo[Board_Manufacturer] = values[1]
|
||||
|
||||
##版本
|
||||
if line.startswith("Version:"):
|
||||
boardinfo[Board_Version] = values[1]
|
||||
|
||||
##芯片组
|
||||
if line.startswith("chipset:"):
|
||||
boardinfo[Board_Chipset] = values[1]
|
||||
|
||||
##SMBIOS版本
|
||||
if line.startswith("Version:"):
|
||||
boardinfo[Board_Version] = values[1]
|
||||
|
||||
##产品名称
|
||||
if line.startswith("Product Name:"):
|
||||
boardinfo[Board_Product] = values[1]
|
||||
|
||||
|
||||
##包含对象程序
|
||||
if line.startswith("Contained Object Handles:"):
|
||||
boardinfo[Board_ContainedObjHandles] = values[1]
|
||||
|
||||
##序列号
|
||||
if line.startswith("Serial Number:"):
|
||||
boardinfo[Board_Serial] = values[1]
|
||||
|
||||
|
||||
##机箱位置
|
||||
if line.startswith("Location In Chassis:"):
|
||||
boardinfo[Board_Location] = values[1]
|
||||
|
||||
|
||||
##机箱程序
|
||||
if line.startswith("Chassis Handle:"):
|
||||
boardinfo[Board_ChassisHandle] = values[1]
|
||||
|
||||
|
||||
##包含“特征”字段
|
||||
if line.startswith("Features:"):
|
||||
hasFeature = True
|
||||
|
||||
##类型
|
||||
if line.startswith("Type:"):
|
||||
boardinfo[Board_Type] = values[1]
|
||||
|
||||
##资产编号
|
||||
if line.startswith("Asset Tag:"):
|
||||
boardinfo[Board_AssetTag] = values[1]
|
||||
##特征
|
||||
if hasFeature:
|
||||
boardinfo[Board_Features] = "\n".join(recordFeature)
|
||||
|
||||
##芯片组
|
||||
if len(boardinfo) > 0 and Board_Chipset not in boardinfo:
|
||||
chipFamily = self.getBaseboardChipFamily()
|
||||
if len(chipFamily) > 0 :
|
||||
boardinfo[Board_Chipset] = chipFamily
|
||||
|
||||
return boardinfo
|
||||
|
||||
def getChassisInfo(self):
|
||||
chassisinfo = {}
|
||||
|
||||
args = ["dmidecode", "-t", "chassis"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
|
||||
marker1 = False
|
||||
|
||||
for line in [ bytes.decode(l.strip(),"utf-8","ignore") for l in output]:
|
||||
# pprint(line)
|
||||
|
||||
###开启机箱信息标志位
|
||||
if line.startswith("Chassis Information"):
|
||||
marker1 = True
|
||||
continue
|
||||
|
||||
if line == "":
|
||||
marker1 = False
|
||||
|
||||
###过滤所有非必要信息
|
||||
if not marker1:
|
||||
continue
|
||||
|
||||
values = [ v.strip() for v in line.split(":", 1)]
|
||||
|
||||
###机箱信息
|
||||
if marker1:
|
||||
|
||||
##制造商
|
||||
if line.startswith("Manufacturer:"):
|
||||
chassisinfo[Chassis_Manufacturer] = values[1]
|
||||
pass
|
||||
|
||||
##版本
|
||||
if line.startswith("Version:"):
|
||||
chassisinfo[Chassis_Version] = values[1]
|
||||
pass
|
||||
|
||||
##OEM信息
|
||||
if line.startswith("OEM Information:"):
|
||||
chassisinfo[Chassis_OEM_Info] = values[1]
|
||||
pass
|
||||
|
||||
##SKU号
|
||||
if line.startswith("SKU Number:"):
|
||||
chassisinfo[Chassis_SKU_Number] = values[1]
|
||||
pass
|
||||
|
||||
##供电状态
|
||||
if line.startswith("Power Supply State:"):
|
||||
chassisinfo[Chassis_PowerSupplyState] = values[1]
|
||||
pass
|
||||
|
||||
##包含组件数
|
||||
if line.startswith("Contained Elements:"):
|
||||
chassisinfo[Chassis_ContainedElements] = values[1]
|
||||
pass
|
||||
|
||||
##序列号
|
||||
if line.startswith("Serial Number:"):
|
||||
chassisinfo[Chassis_SerialNumber] = values[1]
|
||||
pass
|
||||
|
||||
##开机状态
|
||||
if line.startswith("Boot-up State:"):
|
||||
chassisinfo[Chassis_BootUpState] = values[1]
|
||||
pass
|
||||
|
||||
##散热状态
|
||||
if line.startswith("Thermal State:"):
|
||||
chassisinfo[Chassis_ThermalState] = values[1]
|
||||
pass
|
||||
|
||||
##电源线数
|
||||
if line.startswith("Number Of Power Cords:"):
|
||||
chassisinfo[Chassis_Manufacturer] = values[1]
|
||||
pass
|
||||
|
||||
##类型
|
||||
if line.startswith("Type:"):
|
||||
chassisinfo[Chassis_Type] = values[1]
|
||||
pass
|
||||
|
||||
##高度
|
||||
if line.startswith("Height:"):
|
||||
chassisinfo[Chassis_Height] = values[1]
|
||||
pass
|
||||
|
||||
##资产标号
|
||||
if line.startswith("Asset Tag:"):
|
||||
chassisinfo[Chassis_AssetTag] = values[1]
|
||||
pass
|
||||
|
||||
return chassisinfo
|
||||
|
||||
#概要信息
|
||||
def getOutline(self) :
|
||||
outLineObj = self.getBaseBoardInfo()
|
||||
outLine = ""
|
||||
if Board_Product in outLineObj :
|
||||
outLine += outLineObj[Board_Product]
|
||||
return outLine
|
||||
|
||||
if __name__ == "__main__":
|
||||
cc = SystemBoard()
|
||||
#pprint(cc.getSystemBoardInfo())
|
||||
#pprint(cc.getOutline())
|
||||
pprint(cc.getSystemInfo())
|
|
@ -0,0 +1,316 @@
|
|||
|
||||
from ast import Return
|
||||
import os
|
||||
import re
|
||||
import binascii
|
||||
from systemboardthread import *
|
||||
|
||||
KILOBYTE_FACTOR = 1000.0
|
||||
MEGABYTE_FACTOR = (1000.0 * 1000.0)
|
||||
GIGABYTE_FACTOR = (1000.0 * 1000.0 * 1000.0)
|
||||
TERABYTE_FACTOR = (1000.0 * 1000.0 * 1000.0 * 1000.0)
|
||||
|
||||
|
||||
def Judgment_LENOVO():
|
||||
sysBoardInfo = SystemBoard()
|
||||
sysInfo = sysBoardInfo.getSystemInfo()
|
||||
baseBoardInfo = sysBoardInfo.getBaseBoardInfo()
|
||||
customedType = 0 ## 0 通用,1 联想 主板名称:
|
||||
if Board_Manufacturer in baseBoardInfo and "lenovo" in baseBoardInfo[Board_Manufacturer].lower() \
|
||||
and Board_Product in baseBoardInfo and ("FD2000ZX200MB1" in baseBoardInfo[Board_Product]) :
|
||||
customedType = 1
|
||||
return customedType
|
||||
|
||||
def Judgment_TN133A2():
|
||||
# getSystemInfo
|
||||
sysBoardInfo = SystemBoard()
|
||||
sysInfo = sysBoardInfo.getSystemInfo()
|
||||
if System_Product in sysInfo and "长城TN133A2" in sysInfo[System_Product]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def Judgment_PANGUW():
|
||||
args = ["lscpu"]
|
||||
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output = pipe.stdout.readlines()
|
||||
for l in output:
|
||||
line = bytes.decode(l.strip(),"utf-8","ignore")
|
||||
if line.find("PANGU") >= 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def Judgment_HW990():
|
||||
if os.path.exists("/proc/hardware"):
|
||||
with open("/proc/hardware",'r') as fd:
|
||||
info = fd.readline()
|
||||
if info.find("HUAWEI Kirin 990") >= 0 or info.find("kirin990") >= 0 or info.find("HUAWEI Kirin 9006C") >= 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def Judgment_HW9A0():
|
||||
if os.path.exists("/proc/hardware"):
|
||||
with open("/proc/hardware",'r') as fd:
|
||||
info = fd.readline()
|
||||
if info.find("HUAWEI Kirin 9006C") >= 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def myctoascii(buf):
|
||||
ch = bytes(buf.encode('utf-8'))
|
||||
asci = binascii.b2a_hex(ch)
|
||||
asci = int(asci,16)
|
||||
return asci
|
||||
|
||||
def mystrip(s):
|
||||
if(len(s) == 0):
|
||||
return s
|
||||
while len(s) > 0 and myctoascii(s[0]) <= 32:
|
||||
s = s[1: ]
|
||||
k = len(s)
|
||||
while len(s) > 0 and myctoascii(s[k-1]) <= 32:
|
||||
s = s[ :k-1]
|
||||
k = len(s)
|
||||
i = 0
|
||||
while i < len(s):
|
||||
if myctoascii(s[i]) < 32:
|
||||
s = s[ :i] + s[i+1: ]
|
||||
i -= 1
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def get_url(v,p):
|
||||
vendors = {
|
||||
#CPU产商
|
||||
"INTEL":["Intel"],
|
||||
"AMD":["AMD"],
|
||||
"VIMICRO":["Vimicro"],
|
||||
#显卡产商
|
||||
"ATI":["ATI"],
|
||||
"1002":["ATI"],
|
||||
"SIS":["SIS"],
|
||||
"1039":["SIS"],
|
||||
"NVIDIA":["Nvidia"],
|
||||
"VIA":["VIA"],
|
||||
"XFX":["XFX"],
|
||||
"SUPERGRAPHIC":["Supergraphic"],
|
||||
"JINGJIA":["JJM"],
|
||||
"Wuhan Digital Engineering":["WDE"],
|
||||
#显示器产商
|
||||
"AUO":["AUO"],
|
||||
"AOC":["AOC"],
|
||||
"PHILIPS":["Philips"],
|
||||
"PHL":["Philips"],
|
||||
"LEN":["Lenovo"],
|
||||
"SEC":["SAMSUNG"],
|
||||
#电脑品牌
|
||||
"HASEE":["Hasee"],
|
||||
"FOUNDER":["Founder"],
|
||||
"TONGFANG":["Tongfang"],
|
||||
"TSINGHUA":["Tongfang"],
|
||||
"ACER":["Acer"],
|
||||
"LENOVO":["Lenovo"],
|
||||
"ASUSTEK":["ASUS"],
|
||||
"NEC":["NEC"],
|
||||
"HP":["HP"],
|
||||
"HEWLETT-PACKARD":["HP"],
|
||||
"SAMSUNG":["SAMSUNG"],
|
||||
"TOSHIBA":["TOSHIBA"],
|
||||
"APPLE":["Apple"],
|
||||
"DELL":["DELL"],
|
||||
"FUJITSU":["FUJITSU"],
|
||||
"PANASONIC":["Panasonic"],
|
||||
"SONY":["SONY"],
|
||||
"IBM":["IBM"],
|
||||
#虚拟机
|
||||
"INNOTEK":["VirtualBox"],
|
||||
"VBOX":["VirtualBox"],
|
||||
"VIRTUALBOX":["VirtualBox"],
|
||||
#网卡产商
|
||||
"3COM":["3COM"],
|
||||
"D-LINK":["D-LINK"],
|
||||
"RALINK":["Ralink"],
|
||||
"ATHEROS":["Atheros"],
|
||||
"MARVELL":["Marvell"],
|
||||
"BROADCOM":["Broadcom"],
|
||||
#硬盘产商
|
||||
"EXCELSTOR":["Excelstor"],
|
||||
"HITACHI":["Hitachi"],
|
||||
"MAXTOR":["Maxtor"],
|
||||
"WESTERN":["Western Digital"],
|
||||
"LITEON":["Liteon"],
|
||||
"SEAGATE":["Seagate"],
|
||||
"QUANTUM":["Quantum"],
|
||||
#光驱产商
|
||||
"PLDS":["PLDS"],
|
||||
"PBDS":["PLDS"],
|
||||
"HL-DT-ST":["LG"],
|
||||
"OPTIARC":["SONY"],
|
||||
"TSSTCORP":["TSSTcorp"],
|
||||
"PIONEER":["Pioneer"],
|
||||
"MATSHITA":["Panasonic"],
|
||||
#声卡产商
|
||||
"REALTEK":["Realtek"],
|
||||
"CREATIVE":["Creative"],
|
||||
"LOONGSON":["Loongson"],
|
||||
"HISILICON":["HiSilicon"],
|
||||
#摄像头
|
||||
"SONIX":["Sonix"],
|
||||
"ETRON":["Etron"],
|
||||
"AVEO":["Aveo"],
|
||||
"SYNTEK":["Syntek"],
|
||||
"EMPIA":["Empia"],
|
||||
"CHICONY":["Chicony"],
|
||||
"OMNIVISION":["OmniVision"],
|
||||
#鼠标产商
|
||||
"LOGITECH":["Logitech"],
|
||||
"SUNPLUS":["Sunplus"],
|
||||
"PRIMAX":["Primax"],
|
||||
"PIXART":["Pixart"],
|
||||
"TRUST":["Trust"],
|
||||
"1BCF":["Rapoo"],
|
||||
"AVAGO":["Avago"],
|
||||
"MICROSOFT":["Microsoft"],
|
||||
#键盘产商
|
||||
"RAPOO":["Rapoo"],
|
||||
#主板产商
|
||||
"GIGABYTE":["Gigabyte"],
|
||||
"BIOSTAR":["Biostar"],
|
||||
"COLORFUL":["Colorful"],
|
||||
"YESTON":["Yeston"],
|
||||
#指纹识别
|
||||
"UPEK":["Authentec"],
|
||||
"AUTHENTEC":["Authentec"],
|
||||
#闪存产商
|
||||
"KINGSTON":["Kingston"],
|
||||
"KINGMAX":["Kingmax"],
|
||||
"KINGBOX":["Kingbox"],
|
||||
"HYNIX":["Hynix"],
|
||||
"HYUNDAI":["Hynix"],
|
||||
"MICRON":["Micron"],
|
||||
"06C1":["Asint"],
|
||||
"ADATA":["ADATA"],
|
||||
"ZTE":["ZTE"],
|
||||
"EAGET":["Eaget"],
|
||||
"TEXAS":["Texas Instruments"],
|
||||
"MOTOROLA":["Motorola"],
|
||||
#电源产商
|
||||
"SMP":["SMP"],
|
||||
"SIMPLO":["SMP"],
|
||||
#BIOS产商
|
||||
"AMERICAN":["AMI"],
|
||||
"AWARD":["Phoenix"],
|
||||
"PHOENIX":["Phoenix"]
|
||||
}
|
||||
tmp = v.split(" ")[0]
|
||||
tmp = re.findall("([a-zA-Z0-9-]+)", tmp)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else :
|
||||
k = p.split(" ")[0]
|
||||
url = vendors.get(k.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
else:
|
||||
tmp = p.split(" ")[0]
|
||||
url = vendors.get(tmp.upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("JingJia", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Loongson", p, flags=re.IGNORECASE)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("Wuhan Digital Engineering", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
|
||||
tmp = re.findall("ATI", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", v)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("ATI", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("SIS", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
tmp = re.findall("Intel", p)
|
||||
if tmp :
|
||||
url = vendors.get(tmp[0].upper())
|
||||
if url:
|
||||
return url[0]
|
||||
return v
|
||||
|
||||
def exchangeManufacturer(manufacturer) :
|
||||
lowerManufacturer = manufacturer.lower()
|
||||
if "samsung" in lowerManufacturer : ## 三星
|
||||
return "SX"
|
||||
elif "hynix" in lowerManufacturer : ## 海力士
|
||||
return "HL"
|
||||
elif "ramaxel" in lowerManufacturer : ## 记忆
|
||||
return "JY"
|
||||
elif "uniic" in lowerManufacturer : ## 紫光
|
||||
return "ZG"
|
||||
elif "gloway" in lowerManufacturer or "changxin" in lowerManufacturer: ## 长鑫
|
||||
return "CX"
|
||||
elif "crucial" in lowerManufacturer : ## 美光
|
||||
return "MG"
|
||||
elif "western digital" in lowerManufacturer : ## 西数
|
||||
return "XS"
|
||||
elif "toshiba" in lowerManufacturer : ## 东芝
|
||||
return "DZ"
|
||||
elif "ymtc" in lowerManufacturer : ## 长江存储
|
||||
return "CC"
|
||||
elif "goke" in lowerManufacturer : ## 国科微
|
||||
return "GK"
|
||||
elif "biwin" in lowerManufacturer : ## 佰维
|
||||
return "BW"
|
||||
elif "amd" in lowerManufacturer : ## AMD
|
||||
return "AMD"
|
||||
elif "nvidia" in lowerManufacturer : ## Nvidia
|
||||
return "NV"
|
||||
elif "jjm" in lowerManufacturer : ## 景嘉微
|
||||
return "JJW"
|
||||
elif "glenfly" in lowerManufacturer : ## 格兰菲
|
||||
return "GLF"
|
||||
elif lowerManufacturer.startswith("st") : ## 希捷
|
||||
return "XJ"
|
||||
elif "phison" in lowerManufacturer : ## 大唐
|
||||
return "DT"
|
||||
else :
|
||||
return manufacturer
|
||||
|
||||
if __name__ == "__main__":
|
||||
Judgment_TN133A2();
|
|
@ -0,0 +1,15 @@
|
|||
[Desktop Entry]
|
||||
Name=ToolKit
|
||||
Name[zh_CN]=工具箱
|
||||
Name[bo_CN]=ལག་རོགས།
|
||||
GenericName[bo_CN]=ལག་རོགས།
|
||||
Comment=System Auxiliar Tools
|
||||
Comment[zh_CN]=系统辅助工具
|
||||
Comment[bo_CN]=རྒྱུད་ཁོངས་ལས་རོགས་ལག་ཆ།
|
||||
Keywords=Settings;Cleaning;Customization
|
||||
Exec=/usr/bin/kylin-assistant %u
|
||||
Icon=kylin-assistant
|
||||
StartupNotify=true
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=GNOME;GTK;System;Viewer;
|
|
@ -0,0 +1,17 @@
|
|||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
src \
|
||||
plugins \
|
||||
kyasDbus
|
||||
|
||||
TRANSLATIONS += \
|
||||
src/translation/kylin-assistant_zh_CN.ts \
|
||||
src/translation/kylin-assistant_es.ts \
|
||||
src/translation/kylin-assistant_de.ts \
|
||||
src/translation/kylin-assistant_fr.ts \
|
||||
src/translation/kylin-assistant_ru.ts \
|
||||
src/translation/kylin-assistant_bo.ts
|
||||
|
||||
CONFIG += qt
|
||||
|
||||
QT += widgets
|
|
@ -0,0 +1,19 @@
|
|||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH KYLIN-ASSISTANT-SYSTEMDAEMON 1 "03 AUG 2021"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.SH NAME
|
||||
kylin-assistant-systemdaemon \- launch systemdaemon
|
||||
.SH SYNOPSIS
|
||||
.B kylin-assistant-systemdaemon
|
||||
.SH DESCRIPTION
|
||||
.B kylin-assistant-systemdaemon
|
||||
It is used to launch systemdaemon.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
.BR kylin-assistant-systemdaemon (1),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
kylin-assistant-systemdaemon was written by Yang Min <yangmin@kylinos.cn>.
|
||||
.PP
|
||||
This manual page was written by Yang Min <yangmin@kylinos.cn>.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH KYLIN-ASSISTANT 1 "22 DEC 2017"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.SH NAME
|
||||
kylin-assistant \- launch kylin-assistant frontends
|
||||
.SH SYNOPSIS
|
||||
.B kylin-assistant
|
||||
.SH DESCRIPTION
|
||||
.B kylin-assistant
|
||||
It is used to launch frontends.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
.BR kylin-assistant (1),
|
||||
.br
|
||||
.SH AUTHOR
|
||||
kylin-assistant was written by lixiang <lixiang@kylinos.cn>.
|
||||
.PP
|
||||
This manual page was written by lixiang <lixiang@kylinos.cn>.
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "driveinfopage.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QLabel>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QScrollBar>
|
||||
|
||||
DriveInfoPage::DriveInfoPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_strInfoJson = "";
|
||||
initUI();
|
||||
initConnections();
|
||||
}
|
||||
|
||||
void DriveInfoPage::initUI()
|
||||
{
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,24);
|
||||
m_mainLayout->setSpacing(0);
|
||||
m_listLayout = new QVBoxLayout();
|
||||
m_listLayout->setContentsMargins(32,0,0,0);
|
||||
m_listLayout->setSpacing(0);
|
||||
m_listLayout->setAlignment(Qt::AlignTop);
|
||||
m_listFrame = new QFrame();
|
||||
m_listFrame->setLayout(m_listLayout);
|
||||
m_scrollFrame = new QScrollArea();
|
||||
m_scrollFrame->setContentsMargins(0, 0, 0, 0);
|
||||
m_scrollFrame->setBackgroundRole(QPalette::Base);
|
||||
m_scrollFrame->setAutoFillBackground(true);
|
||||
m_scrollFrame->setFrameStyle(0);
|
||||
m_scrollFrame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_scrollFrame->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
m_scrollFrame->setWidgetResizable(true);
|
||||
m_scrollFrame->setWidget(m_listFrame);
|
||||
|
||||
m_mainLayout->addWidget(m_scrollFrame);
|
||||
this->setLayout(m_mainLayout);
|
||||
}
|
||||
|
||||
void DriveInfoPage::clearInfoItems()
|
||||
{
|
||||
QMap<unsigned, QList<KDriveInfoItem*>>::iterator itDriveInfoItems = m_mapItems.begin();
|
||||
for (; itDriveInfoItems != m_mapItems.end(); itDriveInfoItems++) {
|
||||
for (int n = 0; n < itDriveInfoItems.value().size(); n++) {
|
||||
if (itDriveInfoItems.value().at(n)) {
|
||||
delete itDriveInfoItems.value().at(n);
|
||||
}
|
||||
}
|
||||
itDriveInfoItems.value().clear();
|
||||
}
|
||||
m_mapItems.clear();
|
||||
m_mapDriveInfo.clear();
|
||||
}
|
||||
|
||||
void DriveInfoPage::refreshInfoItems()
|
||||
{
|
||||
QMap<DI_TYPE, QList<DriveInfo>>::iterator itDriveInfo = m_mapDriveInfo.begin();
|
||||
int nCurIndex = 0;
|
||||
qInfo()<<"Info Count:"<<m_mapDriveInfo.size();
|
||||
for (; itDriveInfo != m_mapDriveInfo.end(); itDriveInfo++) {
|
||||
qInfo()<<"Info Type:"<<itDriveInfo.key();
|
||||
for (int n = 0; n < itDriveInfo.value().size(); n++) {
|
||||
QString itemIcon = "";
|
||||
QString itemName = "";
|
||||
unsigned uType = DRIVEINFOTYPE_OTHER;
|
||||
DriveInfo driveInfo = itDriveInfo.value().at(n);
|
||||
if (driveInfo.strType == "Host bridge" ||
|
||||
driveInfo.strType == "Signal processing controller" ||
|
||||
driveInfo.strType == "USB controller" ||
|
||||
driveInfo.strType == "PCI bridge" ||
|
||||
driveInfo.strType == "SA bridge") { // 主板
|
||||
itemIcon = ":/imgres/img_res/mother-board.svg";
|
||||
itemName = tr("Motherboard");
|
||||
uType = DRIVEINFOTYPE_MOTHERBOCARD;
|
||||
} else if (driveInfo.strType == "VGA compatible controller") { // 显卡
|
||||
itemIcon = ":/imgres/img_res/graphics-card.svg";
|
||||
itemName = tr("Graphics Card");
|
||||
uType = DRIVEINFOTYPE_GRPHICS;
|
||||
} else if (driveInfo.strType == "Ethernet controller") { // 网卡
|
||||
itemIcon = ":/imgres/img_res/wired.svg";
|
||||
itemName = tr("Wired Network Card");
|
||||
uType = DRIVEINFOTYPE_NETWORK;
|
||||
} else if (driveInfo.strType == "Audio device") { // 声卡
|
||||
itemIcon = ":/imgres/img_res/soundcard.svg";
|
||||
itemName = tr("Sound Card");
|
||||
uType = DRIVEINFOTYPE_AUDIO;
|
||||
} else if (driveInfo.strType == "Network controller") { //无线网卡
|
||||
itemIcon = ":/imgres/img_res/wireless.svg";
|
||||
itemName = tr("Wireless Network Card");
|
||||
uType = DRIVEINFOTYPE_WIFI;
|
||||
} else if (driveInfo.strType == "RAM memory" ||
|
||||
driveInfo.strType == "SATA controller" ||
|
||||
driveInfo.strType == "SMBus") { // 其他
|
||||
itemIcon = ":/imgres/img_res/monitor.svg";
|
||||
itemName = tr("Other");
|
||||
uType = DRIVEINFOTYPE_OTHER;
|
||||
} else {
|
||||
itemIcon = ":/imgres/img_res/monitor.svg";
|
||||
itemName = tr("Other");
|
||||
uType = DRIVEINFOTYPE_OTHER;
|
||||
}
|
||||
KDriveInfoItem *infoItem = new KDriveInfoItem(itemName, itemIcon, driveInfo.strName, driveInfo.strVersion, nCurIndex%2);
|
||||
infoItem->setMinimumHeight(40);
|
||||
infoItem->setFixedWidth(666);
|
||||
m_listLayout->addWidget(infoItem);
|
||||
if (m_mapItems.contains(uType)) {
|
||||
m_mapItems[uType].append(infoItem);
|
||||
} else {
|
||||
QList<KDriveInfoItem*> listItems;
|
||||
listItems.append(infoItem);
|
||||
m_mapItems[uType] = listItems;
|
||||
}
|
||||
nCurIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DI_TYPE DriveInfoPage::getDriveType(QString strType)
|
||||
{
|
||||
if (strType == "Host bridge" ||
|
||||
strType == "Signal processing controller" ||
|
||||
strType == "USB controller" ||
|
||||
strType == "PCI bridge" ||
|
||||
strType == "SA bridge") { // 主板
|
||||
return DRIVEINFOTYPE_MOTHERBOCARD;
|
||||
} else if (strType == "VGA compatible controller") { // 显卡
|
||||
return DRIVEINFOTYPE_GRPHICS;
|
||||
} else if (strType == "Ethernet controller") { // 网卡
|
||||
return DRIVEINFOTYPE_NETWORK;
|
||||
} else if (strType == "Audio device") { // 声卡
|
||||
return DRIVEINFOTYPE_AUDIO;
|
||||
} else if (strType == "Network controller") { //无线网卡
|
||||
return DRIVEINFOTYPE_WIFI;
|
||||
} else if (strType == "RAM memory" ||
|
||||
strType == "SATA controller" ||
|
||||
strType == "SMBus") { // 其他
|
||||
return DRIVEINFOTYPE_OTHER;
|
||||
} else {
|
||||
return DRIVEINFOTYPE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
void DriveInfoPage::onUpdateInfo(QString strInfoJson)
|
||||
{
|
||||
m_strInfoJson = strInfoJson;
|
||||
qInfo()<<"Drive Info:"<<m_strInfoJson;
|
||||
QTimer::singleShot(0, this, [&, this, strInfoJson](){
|
||||
this->updateInfoItems(strInfoJson);
|
||||
});
|
||||
}
|
||||
|
||||
void DriveInfoPage::initConnections()
|
||||
{
|
||||
}
|
||||
|
||||
void DriveInfoPage::updateInfoItems(QString strInfoJson)
|
||||
{
|
||||
if (strInfoJson.isEmpty())
|
||||
return;
|
||||
qInfo()<<"Cur info:"<<strInfoJson;
|
||||
QJsonParseError jsonParseErr;
|
||||
QJsonDocument rootDoc = QJsonDocument::fromJson(strInfoJson.toUtf8(), &jsonParseErr);//字符串格式化为JSON
|
||||
if (jsonParseErr.error != QJsonParseError::NoError) {
|
||||
qWarning() << "JSON格式错误";
|
||||
return;
|
||||
} else {
|
||||
QJsonObject rootObj = rootDoc.object();
|
||||
if (rootObj.isEmpty()) {
|
||||
qWarning() << "JSON串为空";
|
||||
return;
|
||||
}
|
||||
QJsonValue valJson = rootObj.value(DRIVE_INFO);
|
||||
if (valJson.isArray()) {
|
||||
QJsonArray arrayJson = valJson.toArray();
|
||||
clearInfoItems();
|
||||
for (int n = 0; n < arrayJson.size(); n++) {
|
||||
if (arrayJson.at(n).isObject()) {
|
||||
QJsonObject subItemObj = arrayJson.at(n).toObject();
|
||||
QJsonValue subItemValue = subItemObj.value(DRIVE_INFO_TYPE);
|
||||
DriveInfo driveInfo;
|
||||
if (subItemValue.isString()) {
|
||||
driveInfo.strType = subItemValue.toString();
|
||||
}
|
||||
subItemValue = subItemObj.value(DRIVE_INFO_NAME);
|
||||
if (subItemValue.isString()) {
|
||||
driveInfo.strName = subItemValue.toString();
|
||||
}
|
||||
subItemValue = subItemObj.value(DRIVE_INFO_VERSION);
|
||||
if (subItemValue.isString()) {
|
||||
driveInfo.strVersion = subItemValue.toString();
|
||||
}
|
||||
DI_TYPE diType = getDriveType(driveInfo.strType);
|
||||
if (m_mapDriveInfo.contains(diType)) {
|
||||
bool isSameInfo = false;
|
||||
for (int n = 0; n < m_mapDriveInfo[diType].size(); n++) {
|
||||
if (m_mapDriveInfo[diType].at(n).strName == driveInfo.strName) {
|
||||
isSameInfo = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSameInfo) {
|
||||
continue;
|
||||
}
|
||||
m_mapDriveInfo[diType].append(driveInfo);
|
||||
} else {
|
||||
QList<DriveInfo> listDriveInfo;
|
||||
listDriveInfo.append(driveInfo);
|
||||
m_mapDriveInfo[diType] = listDriveInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
refreshInfoItems();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DRIVEINFOPAGE_H
|
||||
#define DRIVEINFOPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QScrollArea>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
#include "kdriveinfoitem.h"
|
||||
#include "../../src/commondef.h"
|
||||
#include "../../src/kajsondef.h"
|
||||
|
||||
enum DI_TYPE{
|
||||
DRIVEINFOTYPE_MOTHERBOCARD, // 主板
|
||||
DRIVEINFOTYPE_GRPHICS, // 显卡
|
||||
DRIVEINFOTYPE_NETWORK, // 有线网卡
|
||||
DRIVEINFOTYPE_AUDIO, // 声卡
|
||||
DRIVEINFOTYPE_WIFI, // 无线网卡
|
||||
DRIVEINFOTYPE_OTHER, // 其他
|
||||
};
|
||||
|
||||
typedef struct _DriveInfo_s
|
||||
{
|
||||
QString strName;
|
||||
QString strType;
|
||||
QString strVersion;
|
||||
}DriveInfo;
|
||||
|
||||
class DriveInfoPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DriveInfoPage(QWidget *parent = nullptr);
|
||||
|
||||
void initUI();
|
||||
|
||||
void initConnections();
|
||||
void updateInfoItems(QString strInfoJson);
|
||||
|
||||
public slots:
|
||||
void onUpdateInfo(QString strInfoJson);
|
||||
|
||||
private:
|
||||
void clearInfoItems();
|
||||
void refreshInfoItems();
|
||||
DI_TYPE getDriveType(QString strType);
|
||||
|
||||
private:
|
||||
QString m_strInfoJson;
|
||||
|
||||
QHBoxLayout *m_mainLayout = nullptr;
|
||||
QFrame *m_listFrame = nullptr;
|
||||
QVBoxLayout *m_listLayout = nullptr;
|
||||
QScrollArea *m_scrollFrame = nullptr;
|
||||
|
||||
QMap<unsigned, QList<KDriveInfoItem*>> m_mapItems;
|
||||
QMap<DI_TYPE, QList<DriveInfo>> m_mapDriveInfo;
|
||||
};
|
||||
|
||||
#endif // DRIVEINFOPAGE_H
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "drivemanage.h"
|
||||
#include "../../src/commondef.h"
|
||||
#include "../../src/kajsondef.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QTimer>
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
DriveManage::DriveManage()
|
||||
{
|
||||
m_pluginName = tr("DriveManager");
|
||||
m_pluginType = DRIVER_MANAGER;
|
||||
mFirstLoad = true;
|
||||
}
|
||||
|
||||
DriveManage::~DriveManage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString DriveManage::getPluginName()
|
||||
{
|
||||
return m_pluginName;
|
||||
}
|
||||
|
||||
int DriveManage::getPluginType()
|
||||
{
|
||||
return m_pluginType;
|
||||
}
|
||||
|
||||
QWidget* DriveManage::getPluginMainWnd()
|
||||
{
|
||||
if (mFirstLoad) {
|
||||
mFirstLoad = false;
|
||||
initUI();
|
||||
initConnections();
|
||||
}
|
||||
return m_pluginWidget;
|
||||
}
|
||||
|
||||
void DriveManage::pluginDelayControl()
|
||||
{
|
||||
// 首次获取驱动信息
|
||||
// getDriveInfo(true);
|
||||
}
|
||||
|
||||
const QString DriveManage::name() const
|
||||
{
|
||||
return QStringLiteral("drivemanager");
|
||||
}
|
||||
|
||||
void DriveManage::updatePluginContent()
|
||||
{
|
||||
qInfo()<<"";
|
||||
getDriveInfo(true);
|
||||
}
|
||||
|
||||
void DriveManage::initUI()
|
||||
{
|
||||
m_pluginWidget = new QWidget();
|
||||
m_pluginWidget->setFixedSize(RIGHT_PANEL_WIDTH, RIGHT_PANEL_HEIGHT);
|
||||
m_pluginWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
m_mainLayout = new QHBoxLayout();
|
||||
m_mainLayout->setContentsMargins(0,0,0,0);
|
||||
m_mainLayout->setSpacing(0);
|
||||
|
||||
m_stackedWidget = new QStackedWidget();
|
||||
// add widget
|
||||
m_loadingWidget = new LoadingWidget();
|
||||
m_stackedWidget->addWidget(m_loadingWidget);
|
||||
// add driveInfo widget
|
||||
m_driveInfoPage = new DriveInfoPage();
|
||||
m_stackedWidget->addWidget(m_driveInfoPage);
|
||||
|
||||
m_mainLayout->addWidget(m_stackedWidget);
|
||||
|
||||
m_pluginWidget->setLayout(m_mainLayout);
|
||||
}
|
||||
|
||||
void DriveManage::initConnections()
|
||||
{
|
||||
}
|
||||
|
||||
void DriveManage::getDriveInfo(bool bReScan)
|
||||
{
|
||||
Q_UNUSED(bReScan);
|
||||
QString strInfoJson = getDriveInfoJson();
|
||||
onUpdateInfo(1, strInfoJson);
|
||||
}
|
||||
|
||||
void DriveManage::onUpdateInfo(unsigned uStatus, QString strInfoJson)
|
||||
{
|
||||
qInfo()<<"updateInfo:"<<uStatus<<","<<strInfoJson;
|
||||
if (uStatus == 0) {
|
||||
m_stackedWidget->setCurrentIndex(0);
|
||||
} else {
|
||||
if (m_driveInfoPage) {
|
||||
m_driveInfoPage->onUpdateInfo(strInfoJson);
|
||||
m_stackedWidget->setCurrentIndex(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DriveManage::isHW990() {
|
||||
QFile file("/proc/cpuinfo");
|
||||
bool isHW990 = false;
|
||||
bool ret = file.open(QIODevice::ReadOnly|QIODevice::Text);
|
||||
if (ret){
|
||||
QString all = file.readAll();
|
||||
if(all.contains("HUAWEI Kirin 990") || all.contains("kirin990") || all.contains("HUAWEI Kirin 9006C") || all.contains("Kirin990")){
|
||||
isHW990 = true;
|
||||
}
|
||||
}
|
||||
return isHW990;
|
||||
}
|
||||
|
||||
QStringList DriveManage::getDeviceDriveInfo()
|
||||
{
|
||||
QString cmd = "lspci -k";
|
||||
|
||||
QProcess *p = new QProcess();
|
||||
p->start(cmd);
|
||||
p->waitForFinished();
|
||||
|
||||
QStringList tmpList;
|
||||
while(p->canReadLine()){
|
||||
QString str = p->readLine();
|
||||
str = str.left(str.length() - 1);
|
||||
tmpList.append(str);
|
||||
}
|
||||
|
||||
QString tmps;
|
||||
QStringList deviceMsgList;
|
||||
for (int i = 0;i < tmpList.size();i ++) {
|
||||
QString str = tmpList.at(i);
|
||||
if(str.startsWith("\t") == false){
|
||||
if(tmps != ""){
|
||||
deviceMsgList.append(tmps);
|
||||
}
|
||||
tmps = str.mid(str.indexOf(" "));
|
||||
}else{
|
||||
QStringList tmparr = str.split(":");
|
||||
if(tmparr.at(0).indexOf("Kernel driver in use") != -1){
|
||||
tmps += ";";
|
||||
tmps += "driver in use:"; //"使用中的驱动:"
|
||||
tmps += tmparr.at(1);
|
||||
}
|
||||
if(tmparr.at(0).indexOf("Kernel modules") != -1){
|
||||
tmps += ";";
|
||||
tmps += "existing drivers:"; //"可选择的驱动:"
|
||||
tmps += tmparr.at(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tmps != ""){
|
||||
deviceMsgList.append(tmps);
|
||||
}
|
||||
if(isHW990()){
|
||||
//add graphics & sound
|
||||
deviceMsgList.append("VGA compatible controller: Mali-G76;driver in use:mali");
|
||||
deviceMsgList.append("Audio device:da_combine_v5;driver in use:hi3xxx_DA_combine_v5");
|
||||
}
|
||||
qDebug() << deviceMsgList;
|
||||
return deviceMsgList;
|
||||
}
|
||||
|
||||
QString DriveManage::getDriveInfoJson()
|
||||
{
|
||||
QJsonObject rootObj;
|
||||
QJsonArray driveArray;
|
||||
QStringList list = getDeviceDriveInfo();
|
||||
for (int i=0 ; i < list.length() ; i++) {
|
||||
if (list[i].isNull() || list[i].isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QString strDriveName;
|
||||
QString strDriveType;
|
||||
QStringList splitlist = list.at(i).split(";");
|
||||
if(splitlist.size() == 1) {
|
||||
//QStringList name = splitlist.at(0).split(":");
|
||||
} else if(splitlist.size() == 2) {
|
||||
if (splitlist[0].isNull() || splitlist[0].isEmpty()
|
||||
|| splitlist[1].isNull() || splitlist[1].isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QStringList name1 = splitlist.at(0).split(":");
|
||||
QStringList name2 = splitlist.at(1).split(":");
|
||||
strDriveType = name1.at(0).trimmed();
|
||||
strDriveName = name2.at(1);
|
||||
} else if(splitlist.size() == 3) {
|
||||
if (splitlist[0].isNull() || splitlist[0].isEmpty()
|
||||
|| splitlist[1].isNull() || splitlist[1].isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
QStringList name3 = splitlist[0].split(":");
|
||||
QStringList name4 = splitlist[1].split(":");
|
||||
//QStringList name5 = splitlist[2].split(":");
|
||||
strDriveType = name3.at(0).trimmed();
|
||||
strDriveName = name4.at(1);
|
||||
}
|
||||
if (!strDriveType.isEmpty()) {
|
||||
QJsonObject oneElement;
|
||||
oneElement.insert(DRIVE_INFO_TYPE, strDriveType);
|
||||
oneElement.insert(DRIVE_INFO_NAME, strDriveName);
|
||||
//oneElement.insert(DRIVE_INFO_VERSION, strDriveName);
|
||||
driveArray.append(oneElement);
|
||||
}
|
||||
}
|
||||
rootObj.insert(DRIVE_INFO, driveArray);
|
||||
QJsonDocument rootDoc;
|
||||
rootDoc.setObject(rootObj);
|
||||
return QString(rootDoc.toJson(QJsonDocument::Compact)); //紧凑格式;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DRIVEMANAGE_H
|
||||
#define DRIVEMANAGE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtPlugin>
|
||||
#include <QWidget>
|
||||
#include <QStackedWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QStringList>
|
||||
|
||||
#include "../../src/interface.h"
|
||||
#include "loadingwidget.h"
|
||||
#include "driveinfopage.h"
|
||||
|
||||
class DriveManage : public QObject, PluginInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID PluginInterfaceIID)
|
||||
Q_INTERFACES(PluginInterface)
|
||||
|
||||
public:
|
||||
DriveManage();
|
||||
virtual ~DriveManage();
|
||||
|
||||
QString getPluginName() Q_DECL_OVERRIDE;
|
||||
int getPluginType() Q_DECL_OVERRIDE;
|
||||
QWidget* getPluginMainWnd() Q_DECL_OVERRIDE;
|
||||
void pluginDelayControl() Q_DECL_OVERRIDE;
|
||||
const QString name() const Q_DECL_OVERRIDE;
|
||||
void updatePluginContent() Q_DECL_OVERRIDE;
|
||||
|
||||
void initUI();
|
||||
void initConnections();
|
||||
void getDriveInfo(bool bReScan = false);
|
||||
|
||||
bool isHW990();
|
||||
QStringList getDeviceDriveInfo();
|
||||
QString getDriveInfoJson();
|
||||
|
||||
public slots:
|
||||
void onUpdateInfo(unsigned uStatus, QString strInfoJson);
|
||||
|
||||
private:
|
||||
QString m_pluginName;
|
||||
int m_pluginType;
|
||||
QWidget *m_pluginWidget = nullptr;
|
||||
bool mFirstLoad;
|
||||
|
||||
QHBoxLayout *m_mainLayout = nullptr;
|
||||
LoadingWidget *m_loadingWidget = nullptr;
|
||||
DriveInfoPage *m_driveInfoPage = nullptr;
|
||||
QStackedWidget *m_stackedWidget = nullptr;
|
||||
};
|
||||
|
||||
#endif // DRIVEMANAGE_H
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
QT += widgets dbus x11extras charts
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += plugin \
|
||||
link_pkgconfig \
|
||||
C++11
|
||||
|
||||
DEFINES += QT_MESSAGELOGCONTEXT
|
||||
|
||||
include(../../env.pri)
|
||||
include(../../CommonControl/CommonControl.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(drivemanage)
|
||||
DESTDIR = ..
|
||||
target.path = $${PLUGIN_INSTALL_DIRS}
|
||||
INSTALLS += target
|
||||
|
||||
LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt
|
||||
|
||||
PKGCONFIG += gsettings-qt
|
||||
|
||||
SOURCES += \
|
||||
driveinfopage.cpp \
|
||||
drivemanage.cpp
|
||||
|
||||
HEADERS += \
|
||||
driveinfopage.h \
|
||||
drivemanage.h
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cpufmpage.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QPalette>
|
||||
#include <kinfolistitem.h>
|
||||
|
||||
#include "../../src/commondef.h"
|
||||
#include "../../src/kajsondef.h"
|
||||
#include "dataworker.h"
|
||||
|
||||
CpuFMPage::CpuFMPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
initUI();
|
||||
initConnections();
|
||||
}
|
||||
|
||||
CpuFMPage::~CpuFMPage()
|
||||
{
|
||||
if (m_styleSettings) {
|
||||
delete m_styleSettings;
|
||||
m_styleSettings = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMPage::initUI()
|
||||
{
|
||||
m_layoutMain = new QVBoxLayout();
|
||||
m_layoutMain->setContentsMargins(0,0,32,0);
|
||||
m_layoutMain->setSpacing(0);
|
||||
// UI布局新增
|
||||
QVBoxLayout *m_layoutTitle = new QVBoxLayout();
|
||||
m_layoutTitle->setContentsMargins(0,0,0,12);
|
||||
m_layoutTitle->setSpacing(0);
|
||||
|
||||
m_layoutMain->setAlignment(Qt::AlignTop);
|
||||
m_layoutFreq = new QHBoxLayout();
|
||||
m_layoutFreq->setContentsMargins(0,0,0,0);
|
||||
m_layoutFreq->setSpacing(0);
|
||||
m_layoutSetting = new QHBoxLayout();
|
||||
m_layoutSetting->setContentsMargins(0,0,0,0);
|
||||
m_layoutSetting->setSpacing(0);
|
||||
m_layoutTips = new QHBoxLayout();
|
||||
m_layoutTips->setContentsMargins(0,0,0,0);
|
||||
m_layoutTips->setSpacing(0);
|
||||
m_layoutFreqRight = new QVBoxLayout();
|
||||
m_layoutFreqRight->setContentsMargins(0,0,0,0);
|
||||
m_layoutFreqRight->setSpacing(0);
|
||||
|
||||
// QLabel* m_titleFreq = new QLabel();
|
||||
m_titleFreq = new QLabel();
|
||||
m_titleFreq->setText(tr("Current CPU frequency"));
|
||||
m_layoutTitle->addWidget(m_titleFreq);
|
||||
m_layoutMain->addLayout(m_layoutTitle);
|
||||
|
||||
m_iconFreq = new QLabel();
|
||||
QPixmap pixmap;
|
||||
pixmap.load(":/imgres/img_res/icon-cpu.svg");
|
||||
pixmap.scaled(42,42);
|
||||
m_iconFreq->setPixmap(pixmap);
|
||||
m_layoutFreq->addWidget(m_iconFreq);
|
||||
|
||||
QHBoxLayout *rightTop = new QHBoxLayout();
|
||||
rightTop->setContentsMargins(0,0,0,0);
|
||||
rightTop->setSpacing(0);
|
||||
QHBoxLayout *rightBottom = new QHBoxLayout();
|
||||
rightBottom->setContentsMargins(0,0,0,0);
|
||||
rightBottom->setSpacing(0);
|
||||
m_labelFreqValue = new QLabel();
|
||||
m_labelFreqValue->setText("0.0GHz");
|
||||
rightTop->addWidget(m_labelFreqValue);
|
||||
rightTop->addStretch(1);
|
||||
m_labelFreq = new QLabel();
|
||||
m_labelFreq->setText(tr("Current average CPU core frequency"));
|
||||
rightBottom->addWidget(m_labelFreq);
|
||||
m_layoutFreqRight->addLayout(rightTop);
|
||||
m_layoutFreqRight->addLayout(rightBottom);
|
||||
|
||||
m_cpuFMSetWidget = new CpuFMSetWidget();
|
||||
m_layoutSetting->addWidget(m_cpuFMSetWidget);
|
||||
|
||||
m_labelTips = new QLabel();
|
||||
m_labelTips->setWordWrap(true);
|
||||
m_labelTips->setText(tr("CPU FM Note: The CPU FM function has some risks, please use it carefully! After FM is completed, restarting will restore the default configuration!"));
|
||||
m_layoutTips->addWidget(m_labelTips);
|
||||
|
||||
m_layoutFreq->addSpacing(12);
|
||||
m_layoutFreq->addLayout(m_layoutFreqRight);
|
||||
// cpu频率背景条
|
||||
m_scrollWidget = new QFrame();
|
||||
m_scrollWidget->setLayout(m_layoutFreq);
|
||||
m_scrollWidget->setStyleSheet("background-color:#f4f5f5;border-radius:6px;");
|
||||
// m_scrollWidget->setBackgroundRole(QPalette::Background);
|
||||
// m_scrollWidget->setBackgroundRole(QPalette::);
|
||||
// m_scrollWidget->setStyleSheet("background: transparent");
|
||||
m_scrollWidget->setContentsMargins(12,10,20,10);
|
||||
// m_scrollFrame = new QScrollArea();
|
||||
// m_scrollFrame->setContentsMargins(0, 0, 0, 0);
|
||||
// m_scrollFrame->setBackgroundRole(QPalette::Base);
|
||||
// m_scrollFrame->setAutoFillBackground(true);
|
||||
// m_scrollFrame->setFrameStyle(0);
|
||||
// m_scrollFrame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
// m_scrollFrame->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
// m_scrollFrame->setWidgetResizable(true);
|
||||
// m_scrollFrame->setWidget(m_scrollWidget);
|
||||
|
||||
|
||||
// m_layoutMain->addLayout(m_layoutFreq);
|
||||
m_layoutMain->addWidget(m_scrollWidget);
|
||||
|
||||
|
||||
// m_layoutMain->addSpacing(24);
|
||||
// m_layoutMain->addLayout(m_layoutSetting);
|
||||
// m_layoutMain->addSpacing(12);
|
||||
// m_layoutMain->addLayout(m_layoutTips);
|
||||
this->setLayout(m_layoutMain);
|
||||
initStyleTheme();
|
||||
if (!DataWorker::getInstance()->getCpuFMEnable()) {
|
||||
m_iconFreq->hide();
|
||||
m_labelFreqValue->hide();
|
||||
m_labelFreq->hide();
|
||||
m_cpuFMSetWidget->hide();
|
||||
m_labelTips->hide();
|
||||
KInfoListItem *listItem = new KInfoListItem("", "", tr("Device not exitst or Get Device is Empty"), 0);
|
||||
listItem->setMinimumHeight(40);
|
||||
listItem->setFixedWidth(666);
|
||||
m_layoutFreq->addWidget(listItem);
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMPage::initStyleTheme()
|
||||
{
|
||||
const QByteArray idd(THEME_QT_SCHEMA);
|
||||
if(QGSettings::isSchemaInstalled(idd)) {
|
||||
m_styleSettings = new QGSettings(idd);
|
||||
}
|
||||
if (m_styleSettings) {
|
||||
connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName") {
|
||||
auto styleNameValue = m_styleSettings->get("styleName");
|
||||
if (styleNameValue.isValid()) {
|
||||
m_strThemeName = styleNameValue.toString();
|
||||
onStyleThemeChange();
|
||||
}
|
||||
} else if (key == "systemFontSize" || key == "systemFont") {
|
||||
auto styleFontSizeValue = m_styleSettings->get(FONT_SIZE);
|
||||
if (styleFontSizeValue.isValid()) {
|
||||
float fFontSize = styleFontSizeValue.toFloat();
|
||||
QFont font = m_labelFreqValue->font();
|
||||
font.setPointSize(fFontSize+2);
|
||||
m_labelFreqValue->setFont(font);
|
||||
m_titleFreq->setFont(font);
|
||||
}
|
||||
}
|
||||
});
|
||||
auto styleNameValue = m_styleSettings->get("styleName");
|
||||
if (styleNameValue.isValid()) {
|
||||
m_strThemeName = styleNameValue.toString();
|
||||
onStyleThemeChange();
|
||||
}
|
||||
auto styleFontSizeValue = m_styleSettings->get(FONT_SIZE);
|
||||
if (styleFontSizeValue.isValid()) {
|
||||
float fFontSize = styleFontSizeValue.toFloat();
|
||||
QFont font = m_labelFreqValue->font();
|
||||
font.setPointSize(fFontSize+2);
|
||||
m_labelFreqValue->setFont(font);
|
||||
m_titleFreq->setFont(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMPage::initConnections()
|
||||
{
|
||||
connect(m_cpuFMSetWidget, &CpuFMSetWidget::modelChanged, this, &CpuFMPage::onCpuFMChange);
|
||||
// 连接dbus信号
|
||||
DataWorker::getInstance()->connectCpuFMInfoSignal();
|
||||
connect(DataWorker::getInstance(), SIGNAL(updateCpuFMInfo(unsigned, QString)), this, SLOT(onUpdateInfo(unsigned, QString)));
|
||||
connect(m_cpuFMSetWidget, &CpuFMSetWidget::updateCpuFreq, this, &CpuFMPage::onUpdateCoreFreq);
|
||||
}
|
||||
|
||||
void CpuFMPage::onCpuFMChange(QString strModel, QString strCurFreq)
|
||||
{
|
||||
qInfo()<<"CurCpuFM:"<<strModel<<","<<strCurFreq;
|
||||
QJsonObject objRoot;
|
||||
objRoot.insert(CPUFM_CURFREQMODEL, strModel);
|
||||
objRoot.insert(CPUFM_CURFREQ, strCurFreq);
|
||||
QJsonDocument rootDoc;
|
||||
rootDoc.setObject(objRoot);
|
||||
QString strAdjust = QString(rootDoc.toJson(QJsonDocument::Compact));
|
||||
DataWorker::getInstance()->setCpuFMInfo(strAdjust);
|
||||
}
|
||||
|
||||
void CpuFMPage::onUpdateCoreFreq(QString strFreq)
|
||||
{
|
||||
m_labelFreqValue->setText(strFreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* {\"cpu_fm\": {\"cpu_model_list\": [\"performance\", \"powersave\"],
|
||||
* \"cpu_freq_list\": [], \"cpu_curmodel\": \"performance\", \"cpu_corefreq\": \"3.6Ghz\"}}
|
||||
*/
|
||||
void CpuFMPage::onUpdateInfo(unsigned uStatus, QString strInfoJson)
|
||||
{
|
||||
//qDebug()<<"CPU FM info:"<<uStatus<<","<<strInfoJson;
|
||||
if (m_cpuFMSetWidget)
|
||||
m_cpuFMSetWidget->onUpdateInfo(strInfoJson);
|
||||
}
|
||||
|
||||
void CpuFMPage::refreshInfo()
|
||||
{
|
||||
DataWorker::getInstance()->getCpuFMInfo();
|
||||
}
|
||||
|
||||
void CpuFMPage::onStyleThemeChange()
|
||||
{
|
||||
QPalette paletteTip = m_labelTips->palette();
|
||||
if (m_strThemeName == "ukui-dark" || m_strThemeName == "ukui-black") {
|
||||
paletteTip.setColor(QPalette::WindowText,QColor("#8c8c8c"));
|
||||
m_scrollWidget->setStyleSheet("background-color:#333333;border-radius:6px;");
|
||||
} else { // "ukui-default" "ukui-white" "ukui-light" "ukui"
|
||||
paletteTip.setColor(QPalette::WindowText,QColor("#8c8c8c"));
|
||||
m_scrollWidget->setStyleSheet("background-color:#f4f5f5;border-radius:6px;");
|
||||
}
|
||||
m_labelTips->setPalette(paletteTip);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CPUFMPAGE_H
|
||||
#define CPUFMPAGE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <qgsettings.h>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "cpufmsetwidget.h"
|
||||
|
||||
class CpuFMPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CpuFMPage(QWidget *parent = nullptr);
|
||||
virtual ~CpuFMPage();
|
||||
|
||||
void initUI();
|
||||
void initConnections();
|
||||
void refreshInfo();
|
||||
|
||||
public slots:
|
||||
void onCpuFMChange(QString strModel, QString strCurFreq);
|
||||
void onUpdateInfo(unsigned uStatus, QString strInfoJson);
|
||||
void onUpdateCoreFreq(QString strFreq);
|
||||
|
||||
private:
|
||||
void initStyleTheme();
|
||||
void onStyleThemeChange();
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_layoutMain = nullptr;
|
||||
QHBoxLayout *m_layoutFreq = nullptr;
|
||||
QHBoxLayout *m_layoutSetting = nullptr;
|
||||
QHBoxLayout *m_layoutTips = nullptr;
|
||||
QVBoxLayout *m_layoutFreqRight = nullptr;
|
||||
|
||||
CpuFMSetWidget *m_cpuFMSetWidget = nullptr;
|
||||
QLabel *m_iconFreq = nullptr;
|
||||
QLabel *m_labelFreqValue = nullptr;
|
||||
QLabel *m_labelFreq = nullptr;
|
||||
QLabel *m_labelTips = nullptr;
|
||||
QLabel *m_titleFreq = nullptr;
|
||||
QFrame *m_scrollWidget = nullptr;
|
||||
|
||||
QGSettings *m_styleSettings = nullptr;
|
||||
QString m_strThemeName = "";
|
||||
};
|
||||
|
||||
#endif // CPUFMPAGE_H
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cpufmsetwidget.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QDebug>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "../../src/commondef.h"
|
||||
#include "../../src/kajsondef.h"
|
||||
|
||||
CpuFMSetWidget::CpuFMSetWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
m_alternateBase = palette().alternateBase().color();
|
||||
initUI();
|
||||
initConnections();
|
||||
}
|
||||
|
||||
CpuFMSetWidget::~CpuFMSetWidget()
|
||||
{
|
||||
if (m_styleSettings) {
|
||||
delete m_styleSettings;
|
||||
m_styleSettings = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
QPainterPath path;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(1);
|
||||
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
painter.setClipping(true);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
path.addRoundedRect(this->rect(), 6.0, 6.0);
|
||||
path.setFillRule(Qt::WindingFill);
|
||||
QBrush brush = this->palette().alternateBase();
|
||||
brush.setColor(m_alternateBase);
|
||||
painter.setBrush(brush);
|
||||
painter.setPen(Qt::transparent);
|
||||
|
||||
painter.drawPath(path);
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::initUI()
|
||||
{
|
||||
m_layoutMain = new QVBoxLayout();
|
||||
m_layoutMain->setContentsMargins(16,4,28,0);
|
||||
m_layoutMain->setSpacing(0);
|
||||
m_layoutTitle = new QHBoxLayout();
|
||||
m_layoutTitle->setContentsMargins(0,0,0,0);
|
||||
m_layoutTitle->setSpacing(0);
|
||||
m_layoutSingleChk = new QHBoxLayout();
|
||||
m_layoutSingleChk->setContentsMargins(0,0,0,0);
|
||||
m_layoutSingleChk->setSpacing(0);
|
||||
m_layoutSlider = new QHBoxLayout();
|
||||
m_layoutSlider->setContentsMargins(0,0,0,0);
|
||||
m_layoutSlider->setSpacing(0);
|
||||
|
||||
m_labelTitle = new KAInfoTitle(tr("CPU Management Strategy"));
|
||||
m_labelTitle->setMinimumHeight(36);
|
||||
m_layoutTitle->addWidget(m_labelTitle);
|
||||
m_layoutTitle->addStretch(1);
|
||||
|
||||
m_bgRadio = new QButtonGroup(this);
|
||||
m_bgRadio->setExclusive(true);
|
||||
m_radioPerformance = new QRadioButton();
|
||||
m_radioPerformance->setText(tr("performance"));
|
||||
m_radioPerformance->setObjectName("performance");
|
||||
m_radioPerformance->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioPerformance);
|
||||
m_bgRadio->addButton(m_radioPerformance);
|
||||
|
||||
m_radioPowerSave = new QRadioButton();
|
||||
m_radioPowerSave->setText(tr("powersave"));
|
||||
m_radioPowerSave->setObjectName("powersave");
|
||||
m_radioPowerSave->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioPowerSave);
|
||||
m_bgRadio->addButton(m_radioPowerSave);
|
||||
|
||||
m_radioUserSpace = new QRadioButton();
|
||||
m_radioUserSpace->setText(tr("userspace"));
|
||||
m_radioUserSpace->setObjectName("userspace");
|
||||
m_radioUserSpace->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioUserSpace);
|
||||
m_bgRadio->addButton(m_radioUserSpace);
|
||||
|
||||
m_radioBalance = new QRadioButton();
|
||||
m_radioBalance->setText(tr("schedutil"));
|
||||
m_radioBalance->setObjectName("schedutil");
|
||||
m_radioBalance->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioBalance);
|
||||
m_bgRadio->addButton(m_radioBalance);
|
||||
|
||||
m_radioOndemand = new QRadioButton();
|
||||
m_radioOndemand->setText(tr("ondemand"));
|
||||
m_radioOndemand->setObjectName("ondemand");
|
||||
m_radioOndemand->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioOndemand);
|
||||
m_bgRadio->addButton(m_radioOndemand);
|
||||
|
||||
m_radioConservative = new QRadioButton();
|
||||
m_radioConservative->setText(tr("conservative"));
|
||||
m_radioConservative->setObjectName("conservative");
|
||||
m_radioConservative->hide();
|
||||
m_layoutSingleChk->addWidget(m_radioConservative);
|
||||
m_bgRadio->addButton(m_radioConservative);
|
||||
|
||||
m_layoutSingleChk->setSpacing(10);
|
||||
m_layoutSingleChk->addStretch(1);
|
||||
m_layoutSingleChk->setContentsMargins(12, 0, 0, 0);
|
||||
|
||||
QStringList strList;
|
||||
strList << "2.5GHz" << "2.8GHz" << "3.0GHz" << "3.6GHz" << "4.0GHz";
|
||||
m_sliderUserSpace = new KASlider(strList);
|
||||
m_sliderUserSpace->setRange(0,strList.size()-1);
|
||||
m_sliderUserSpace->setTickInterval(1);
|
||||
m_sliderUserSpace->setPageStep(1);
|
||||
m_sliderUserSpace->hide();
|
||||
m_layoutSlider->addSpacing(12);
|
||||
m_layoutSlider->addWidget(m_sliderUserSpace);
|
||||
|
||||
m_layoutMain->setSpacing(18);
|
||||
m_layoutMain->addLayout(m_layoutTitle);
|
||||
m_layoutMain->addLayout(m_layoutSingleChk);
|
||||
m_layoutMain->addLayout(m_layoutSlider);
|
||||
m_layoutMain->addSpacing(16);
|
||||
this->setLayout(m_layoutMain);
|
||||
initStyleTheme();
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::initStyleTheme()
|
||||
{
|
||||
const QByteArray idd(THEME_QT_SCHEMA);
|
||||
if(QGSettings::isSchemaInstalled(idd)) {
|
||||
m_styleSettings = new QGSettings(idd);
|
||||
}
|
||||
if (m_styleSettings) {
|
||||
connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) {
|
||||
if (key == "styleName") {
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
auto styleNameValue = m_styleSettings->get(MODE_QT_KEY);
|
||||
if (styleNameValue.isValid()) {
|
||||
auto styleName = styleNameValue.toString();
|
||||
if (styleName == "ukui-black" || styleName == "ukui-dark") {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_DARK);
|
||||
} else {
|
||||
m_alternateBase = QColor(COLOR_ALTERNATEBASE_LIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::initConnections()
|
||||
{
|
||||
connect(m_bgRadio, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*)));
|
||||
connect(m_sliderUserSpace, &QSlider::valueChanged, [=](int value){
|
||||
qInfo()<<"SetCpuFreq:"<<value;
|
||||
if (m_strCurModel != m_radioUserSpace->objectName()) {
|
||||
return;
|
||||
}
|
||||
m_strCurFreq = m_sliderUserSpace->valueList().at(value);
|
||||
Q_EMIT modelChanged(m_strCurModel, m_strCurFreq);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {\"cpu_fm\": {\"cpu_model_list\": [\"performance\", \"powersave\"],
|
||||
* \"cpu_freq_list\": [], \"cpu_curmodel\": \"performance\", \"cpu_corefreq\": \"3.6Ghz\"}}
|
||||
*/
|
||||
void CpuFMSetWidget::onUpdateInfo(QString strInfoJson)
|
||||
{
|
||||
if (strInfoJson.isEmpty())
|
||||
return;
|
||||
QJsonParseError jsonParseErr;
|
||||
QJsonDocument rootDoc = QJsonDocument::fromJson(strInfoJson.toUtf8(), &jsonParseErr);//字符串格式化为JSON
|
||||
if (jsonParseErr.error != QJsonParseError::NoError) {
|
||||
qWarning() << "JSON格式错误";
|
||||
return;
|
||||
} else {
|
||||
QJsonObject rootObj = rootDoc.object();
|
||||
if (rootObj.isEmpty()) {
|
||||
qWarning() << "JSON串为空";
|
||||
return;
|
||||
}
|
||||
QJsonValue valJson = rootObj.value(CPUFM_ROOT);
|
||||
if (valJson.isObject()) {
|
||||
QJsonObject objCPUFM = valJson.toObject();
|
||||
QJsonValue valCoreFreq = objCPUFM.value(CPUFM_AVERAGE_COREFREQ);
|
||||
if (valCoreFreq.isString()) {
|
||||
Q_EMIT updateCpuFreq(valCoreFreq.toString());
|
||||
}
|
||||
QJsonValue valModel = objCPUFM.value(CPUFM_CURFREQMODEL);
|
||||
if (valModel.isString()) {
|
||||
m_strCurModel = valModel.toString();
|
||||
}
|
||||
QJsonValue valFreq = objCPUFM.value(CPUFM_CURFREQ);
|
||||
if (valFreq.isString()) {
|
||||
m_strCurFreq = valFreq.toString();
|
||||
}
|
||||
QJsonValue valFreqList = objCPUFM.value(CPUFM_FREQS);
|
||||
if (valFreqList.isArray()) {
|
||||
QJsonArray arrayJson = valFreqList.toArray();
|
||||
m_validFreqList.clear();
|
||||
for (int n = 0; n < arrayJson.size(); n++) {
|
||||
if (arrayJson.at(n).isString()) {
|
||||
m_validFreqList.append(arrayJson.at(n).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
QJsonValue valModelList = objCPUFM.value(CPUFM_MODELS);
|
||||
if (valModelList.isArray()) {
|
||||
QJsonArray arrayJson = valModelList.toArray();
|
||||
m_validModelList.clear();
|
||||
for (int n = 0; n < arrayJson.size(); n++) {
|
||||
if (arrayJson.at(n).isString()) {
|
||||
m_validModelList.append(arrayJson.at(n).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
updateUIStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::onButtonClicked(QAbstractButton* button)
|
||||
{
|
||||
QRadioButton* radioBtn = qobject_cast<QRadioButton*>(button);
|
||||
if (radioBtn) {
|
||||
qInfo()<<"objName:"<<radioBtn->objectName();
|
||||
m_strCurModel = radioBtn->objectName();
|
||||
if (radioBtn != m_radioUserSpace) {
|
||||
Q_EMIT modelChanged(m_strCurModel, "");
|
||||
if (!m_sliderUserSpace->isHidden())
|
||||
m_sliderUserSpace->hide();
|
||||
} else {
|
||||
if (m_sliderUserSpace->valueList().contains(m_strCurFreq)) {
|
||||
Q_EMIT modelChanged(m_strCurModel, m_strCurFreq);
|
||||
} else {
|
||||
m_sliderUserSpace->setValue(0);
|
||||
m_strCurFreq = m_sliderUserSpace->valueList().at(0);
|
||||
Q_EMIT modelChanged(m_strCurModel, m_strCurFreq);
|
||||
}
|
||||
if (m_sliderUserSpace->isHidden())
|
||||
m_sliderUserSpace->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CpuFMSetWidget::updateUIStatus()
|
||||
{
|
||||
if (m_validModelList.contains(CPUFM_MODEL_PERFORMANCE)) {
|
||||
m_radioPerformance->show();
|
||||
}
|
||||
if (m_validModelList.contains(CPUFM_MODEL_POWERSAVE)) {
|
||||
m_radioPowerSave->show();
|
||||
}
|
||||
if (m_validModelList.contains(CPUFM_MODEL_USERSPACE)) {
|
||||
m_radioUserSpace->show();
|
||||
}
|
||||
if (m_validModelList.contains(CPUFM_MODEL_SCHEDUTIL)) {
|
||||
m_radioBalance->show();
|
||||
}
|
||||
if (m_validModelList.contains(CPUFM_MODEL_ONDEMAND)) {
|
||||
m_radioOndemand->show();
|
||||
}
|
||||
if (m_validModelList.contains(CPUFM_MODEL_CONSERVATIVE)) {
|
||||
m_radioConservative->show();
|
||||
}
|
||||
if (!m_validFreqList.empty()) {
|
||||
m_sliderUserSpace->setValueList(m_validFreqList);
|
||||
m_sliderUserSpace->setRange(0,m_validFreqList.size()-1);
|
||||
m_sliderUserSpace->setTickInterval(1);
|
||||
m_sliderUserSpace->setPageStep(1);
|
||||
if (m_validFreqList.contains(m_strCurFreq)) {
|
||||
m_sliderUserSpace->setValue(m_validFreqList.indexOf(m_strCurFreq));
|
||||
}
|
||||
}
|
||||
if (m_strCurModel == CPUFM_MODEL_PERFORMANCE) {
|
||||
m_radioPerformance->setChecked(true);
|
||||
m_radioPowerSave->setChecked(false);
|
||||
m_radioUserSpace->setChecked(false);
|
||||
m_radioBalance->setChecked(false);
|
||||
m_radioOndemand->setChecked(false);
|
||||
m_radioConservative->setChecked(false);
|
||||
m_sliderUserSpace->hide();
|
||||
} else if (m_strCurModel == CPUFM_MODEL_POWERSAVE) {
|
||||
m_radioPerformance->setChecked(false);
|
||||
m_radioPowerSave->setChecked(true);
|
||||
m_radioUserSpace->setChecked(false);
|
||||
m_radioBalance->setChecked(false);
|
||||
m_radioOndemand->setChecked(false);
|
||||
m_radioConservative->setChecked(false);
|
||||
m_sliderUserSpace->hide();
|
||||
} else if (m_strCurModel == CPUFM_MODEL_USERSPACE) {
|
||||
m_radioPerformance->setChecked(false);
|
||||
m_radioPowerSave->setChecked(false);
|
||||
m_radioUserSpace->setChecked(true);
|
||||
m_radioBalance->setChecked(false);
|
||||
m_radioOndemand->setChecked(false);
|
||||
m_radioConservative->setChecked(false);
|
||||
m_sliderUserSpace->show();
|
||||
} else if (m_strCurModel == CPUFM_MODEL_SCHEDUTIL) {
|
||||
m_radioPerformance->setChecked(false);
|
||||
m_radioPowerSave->setChecked(false);
|
||||
m_radioUserSpace->setChecked(false);
|
||||
m_radioBalance->setChecked(true);
|
||||
m_radioOndemand->setChecked(false);
|
||||
m_radioConservative->setChecked(false);
|
||||
m_sliderUserSpace->hide();
|
||||
} else if (m_strCurModel == CPUFM_MODEL_ONDEMAND) {
|
||||
m_radioPerformance->setChecked(false);
|
||||
m_radioPowerSave->setChecked(false);
|
||||
m_radioUserSpace->setChecked(false);
|
||||
m_radioBalance->setChecked(false);
|
||||
m_radioOndemand->setChecked(true);
|
||||
m_radioConservative->setChecked(false);
|
||||
m_sliderUserSpace->hide();
|
||||
} else if (m_strCurModel == CPUFM_MODEL_CONSERVATIVE) {
|
||||
m_radioPerformance->setChecked(false);
|
||||
m_radioPowerSave->setChecked(false);
|
||||
m_radioUserSpace->setChecked(false);
|
||||
m_radioBalance->setChecked(false);
|
||||
m_radioOndemand->setChecked(false);
|
||||
m_radioConservative->setChecked(true);
|
||||
m_sliderUserSpace->hide();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (C) 2021 KylinSoft Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Yang Min yangmin@kylinos.cn
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CPUFMSETWIDGET_H
|
||||
#define CPUFMSETWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QButtonGroup>
|
||||
#include <QRadioButton>
|
||||
#include <qgsettings.h>
|
||||
#include <QStringList>
|
||||
|
||||
#include "kainfotitle.h"
|
||||
#include "kaslider.h"
|
||||
|
||||
class CpuFMSetWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CpuFMSetWidget(QWidget *parent = nullptr);
|
||||
virtual ~CpuFMSetWidget();
|
||||
|
||||
void initUI();
|
||||
void initConnections();
|
||||
|
||||
public slots:
|
||||
void onUpdateInfo(QString strInfoJson);
|
||||
void onButtonClicked(QAbstractButton* button);
|
||||
|
||||
signals:
|
||||
void updateCpuFreq(QString strFreq);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
void initStyleTheme();
|
||||
void updateUIStatus();
|
||||
|
||||
signals:
|
||||
void modelChanged(QString strModel, QString strFreq);
|
||||
|
||||
private:
|
||||
QVBoxLayout *m_layoutMain = nullptr;
|
||||
QHBoxLayout *m_layoutTitle = nullptr;
|
||||
QHBoxLayout *m_layoutSingleChk = nullptr;
|
||||
QHBoxLayout *m_layoutSlider = nullptr;
|
||||
|
||||
KAInfoTitle *m_labelTitle = nullptr;
|
||||
QButtonGroup *m_bgRadio = nullptr;
|
||||
QRadioButton *m_radioPerformance = nullptr;
|
||||
QRadioButton *m_radioPowerSave = nullptr;
|
||||
QRadioButton *m_radioUserSpace = nullptr;
|
||||
QRadioButton *m_radioBalance = nullptr;
|
||||
QRadioButton *m_radioOndemand = nullptr;
|
||||
QRadioButton *m_radioConservative = nullptr;
|
||||
|
||||
KASlider *m_sliderUserSpace = nullptr;
|
||||
|
||||
QString m_strCurModel;
|
||||
QString m_strCurFreq;
|
||||
|
||||
QGSettings *m_styleSettings = nullptr;
|
||||
QColor m_alternateBase;
|
||||
QStringList m_validFreqList;
|
||||
QStringList m_validModelList;
|
||||
};
|
||||
|
||||
#endif // CPUFMSETWIDGET_H
|