Import Upstream version 3.0.2.0kylin6k70.30update1

This commit is contained in:
谢炜 2022-06-02 16:30:40 +08:00
commit c387c041e4
233 changed files with 36670 additions and 0 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

34
CommonControl/kalabel.cpp Normal file
View File

@ -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);
}

23
CommonControl/kalabel.h Normal file
View File

@ -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

View File

@ -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();
}

44
CommonControl/kaslider.h Normal file
View File

@ -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

352
CommonControl/katabbar.cpp Normal file
View File

@ -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();
}

85
CommonControl/katabbar.h Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

40
README.md Normal file
View File

@ -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

View File

@ -0,0 +1,6 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += \
$$PWD/utils.h
SOURCES += \
$$PWD/utils.cpp

83
commonfunc/utils.cpp Normal file
View File

@ -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;
}

35
commonfunc/utils.h Normal file
View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

@ -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)
2Memory: displays details of the computer's memory.
![Fig 4 Memory-big](image/3.png)
3Click other items to switch to the hardware details tab.
![Fig 5 MotherBoard-big](image/4.png)
<br>
## HardwareMonitoring
1Equipment monitoring, users can view the temperature and utilization of hardware equipment.
![Fig 6 Device Monitor-big](image/5.png)
2CPU 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>

BIN
data/toolkit/toolkit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -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)
2CPU调频用户可设置CPU管理策略。
注意不同机器下CPU管理策略可能有差异以下内容仅供参考
![图 7 CPU调频-big](image/6.png)
自定义模式如图8所示。
![图 8 自定义模式](image/7.png)
<br>
## 驱动管理
界面如图9所示显示了计算机中的各个驱动信息。
![图 9 驱动管理-big](image/8.png)
<br>

1137
dataworker/dataworker.cpp Normal file

File diff suppressed because it is too large Load Diff

156
dataworker/dataworker.h Normal file
View File

@ -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

View File

@ -0,0 +1,6 @@
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += \
$$PWD/dataworker.h
SOURCES += \
$$PWD/dataworker.cpp

4
env.pri Normal file
View File

@ -0,0 +1,4 @@
PROJECT_ROOTDIR = $$PWD
PROJECT_COMPONENTLIBS = $$PWD/cclibs
PROJECT_COMPONENTSOURCE = $$PWD/commonComponent
PLUGIN_INSTALL_DIRS = $$[QT_INSTALL_LIBS]/kylin-assistant

20
kyasDbus/kyasDbus.pro Normal file
View File

@ -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 \

View File

@ -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())

View File

@ -0,0 +1,3 @@
[D-BUS Service]
Name=com.kylin.assistant.sessiondaemon
Exec=/usr/bin/kylin-assistant-sessiondaemon.py

View File

@ -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)

View File

@ -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()

View File

@ -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" #转速

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,4 @@
[D-BUS Service]
Name=com.kylin.assistant.systemdaemon
Exec=/usr/bin/kylin-assistant-systemdaemon.py
User=root

View File

@ -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())

View File

@ -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())

View File

@ -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())

View File

@ -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())

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -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())

View File

@ -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)

View File

@ -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()

View File

@ -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" #转速

View File

@ -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())

View File

@ -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())

View File

@ -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())

View File

@ -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())

View File

@ -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

View File

@ -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())

View File

@ -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()

View File

@ -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

View File

@ -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))

View File

@ -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())

View File

@ -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())

View File

@ -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();

15
kylin-assistant.desktop Normal file
View File

@ -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;

17
kylin-assistant.pro Normal file
View File

@ -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

View File

@ -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>.

19
man/kylin-assistant.1 Normal file
View File

@ -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>.

View File

@ -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();
}
}
}

View File

@ -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

View File

@ -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)); //紧凑格式;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More