[cosmetics] convert CRLF to LF line endings

This commit is contained in:
Rechi 2025-08-22 13:01:38 -04:00
parent 2a3fcb901c
commit 0ec0fddaad
27 changed files with 2683 additions and 2683 deletions

View File

@ -1,282 +1,282 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-------------------------------------------------------------------------

View File

@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
__all__ = ['runner', 'version_check']
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
__all__ = ['runner', 'version_check']

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from version_check import service # pylint: disable=import-error
service.run()
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from version_check import service # pylint: disable=import-error
service.run()

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
__all__ = ['apt_daemon_handler', 'common', 'handler', 'json_interface', 'service',
'shell_handler_apt', 'versions', 'viewer']
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
__all__ = ['apt_daemon_handler', 'common', 'handler', 'json_interface', 'service',
'shell_handler_apt', 'versions', 'viewer']

View File

@ -1,120 +1,120 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import log
from .handler import Handler
try:
import apt
from aptdaemon import client
from aptdaemon import errors
except ImportError:
apt = None
client = None
errors = None
log('ImportError: apt, aptdaemon')
class AptDaemonHandler(Handler):
""" Apt daemon handler
"""
def __init__(self):
Handler.__init__(self)
self.apt_client = client.AptClient()
def _check_versions(self, package):
""" Check apt package versions
:param package: package to check
:type package: str
:return: installed version, candidate version
:rtype: str, str / False, False
"""
if self.update and not self._update_cache():
return False, False
try:
trans = self.apt_client.upgrade_packages([package])
# trans = self.apt_client.upgrade_packages('bla')
trans.simulate(reply_handler=self._apt_trans_started,
error_handler=self._apt_error_handler)
pkg = trans.packages[4][0]
if pkg == package:
cache = apt.Cache()
cache.open(None)
cache.upgrade()
if cache[pkg].installed:
return cache[pkg].installed.version, cache[pkg].candidate.version
return False, False
except Exception as error: # pylint: disable=broad-except
log('Exception while checking versions: %s' % error)
return False, False
def _update_cache(self):
""" Update apt client cache
:return: success of updating apt cache
:rtype: bool
"""
try:
return self.apt_client.update_cache(wait=True) == 'exit-success'
except errors.NotAuthorizedError:
log('You are not allowed to update the cache')
return False
def upgrade_package(self, package):
""" Upgrade apt package
:param package: package to upgrade
:type package: str
:return: success of apt package upgrade
:rtype: bool
"""
try:
log('Installing new version')
if self.apt_client.upgrade_packages([package], wait=True) == 'exit-success':
log('Upgrade successful')
return True
except Exception as error: # pylint: disable=broad-except
log('Exception during upgrade: %s' % error)
return False
def upgrade_system(self):
""" Upgrade system
:return: success of system upgrade
:rtype: bool
"""
try:
log('Upgrading system')
if self.apt_client.upgrade_system(wait=True) == 'exit-success':
return True
except Exception as error: # pylint: disable=broad-except
log('Exception during system upgrade: %s' % error)
return False
def _apt_trans_started(self):
""" Apt transfer reply handler
"""
@staticmethod
def _apt_error_handler(error):
""" Apt transfer error handler
:param error: apt error message
:type error: str
"""
log('Apt Error %s' % error)
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import log
from .handler import Handler
try:
import apt
from aptdaemon import client
from aptdaemon import errors
except ImportError:
apt = None
client = None
errors = None
log('ImportError: apt, aptdaemon')
class AptDaemonHandler(Handler):
""" Apt daemon handler
"""
def __init__(self):
Handler.__init__(self)
self.apt_client = client.AptClient()
def _check_versions(self, package):
""" Check apt package versions
:param package: package to check
:type package: str
:return: installed version, candidate version
:rtype: str, str / False, False
"""
if self.update and not self._update_cache():
return False, False
try:
trans = self.apt_client.upgrade_packages([package])
# trans = self.apt_client.upgrade_packages('bla')
trans.simulate(reply_handler=self._apt_trans_started,
error_handler=self._apt_error_handler)
pkg = trans.packages[4][0]
if pkg == package:
cache = apt.Cache()
cache.open(None)
cache.upgrade()
if cache[pkg].installed:
return cache[pkg].installed.version, cache[pkg].candidate.version
return False, False
except Exception as error: # pylint: disable=broad-except
log('Exception while checking versions: %s' % error)
return False, False
def _update_cache(self):
""" Update apt client cache
:return: success of updating apt cache
:rtype: bool
"""
try:
return self.apt_client.update_cache(wait=True) == 'exit-success'
except errors.NotAuthorizedError:
log('You are not allowed to update the cache')
return False
def upgrade_package(self, package):
""" Upgrade apt package
:param package: package to upgrade
:type package: str
:return: success of apt package upgrade
:rtype: bool
"""
try:
log('Installing new version')
if self.apt_client.upgrade_packages([package], wait=True) == 'exit-success':
log('Upgrade successful')
return True
except Exception as error: # pylint: disable=broad-except
log('Exception during upgrade: %s' % error)
return False
def upgrade_system(self):
""" Upgrade system
:return: success of system upgrade
:rtype: bool
"""
try:
log('Upgrading system')
if self.apt_client.upgrade_system(wait=True) == 'exit-success':
return True
except Exception as error: # pylint: disable=broad-except
log('Exception during system upgrade: %s' % error)
return False
def _apt_trans_started(self):
""" Apt transfer reply handler
"""
@staticmethod
def _apt_error_handler(error):
""" Apt transfer error handler
:param error: apt error message
:type error: str
"""
log('Apt Error %s' % error)

View File

@ -1,288 +1,288 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import sys
import xbmc # pylint: disable=import-error
import xbmcaddon # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
try:
xbmc.translatePath = xbmcvfs.translatePath
except AttributeError:
pass
ADDON = xbmcaddon.Addon('service.xbmc.versioncheck')
ADDON_VERSION = ADDON.getAddonInfo('version')
ADDON_NAME = ADDON.getAddonInfo('name')
if sys.version_info[0] >= 3:
ADDON_PATH = ADDON.getAddonInfo('path')
ADDON_PROFILE = xbmc.translatePath(ADDON.getAddonInfo('profile'))
else:
ADDON_PATH = ADDON.getAddonInfo('path').decode('utf-8')
ADDON_PROFILE = xbmc.translatePath(ADDON.getAddonInfo('profile')).decode('utf-8')
ICON = ADDON.getAddonInfo('icon')
KODI_VERSION_MAJOR = int(xbmc.getInfoLabel('System.BuildVersion')[0:2])
MONITOR = xbmc.Monitor()
# Fixes unicode problems
def string_unicode(text, encoding='utf-8'):
""" Python 2/3 -> unicode/str
:param text: text to convert
:type text: unicode (py2) / str (py3) / bytes (py3)
:param encoding: text encoding
:type encoding: str
:return: converted text
:rtype: unicode (py2) / str (py3)
"""
try:
if sys.version_info[0] >= 3:
text = str(text)
else:
text = unicode(text, encoding) # pylint: disable=undefined-variable
except: # pylint: disable=bare-except
pass
return text
def normalize_string(text):
""" Normalize string
:param text: text to normalize
:type text: unicode (py2) / str (py3) / bytes (py3)
:return: normalized text
:rtype: unicode (py2) / str (py3)
"""
try:
text = unicodedata.normalize('NFKD', string_unicode(text)).encode('ascii', 'ignore') # pylint: disable=undefined-variable
except: # pylint: disable=bare-except
pass
return text
def localise(string_id):
""" Localise string id
:param string_id: id of the string to localise
:type string_id: int
:return: localised string
:rtype: unicode (py2) / str (py3)
"""
string = normalize_string(ADDON.getLocalizedString(string_id))
return string
def log(txt):
""" Log text at xbmc.LOGDEBUG level
:param txt: text to log
:type txt: str / unicode / bytes (py3)
"""
if sys.version_info[0] >= 3:
if isinstance(txt, bytes):
txt = txt.decode('utf-8')
message = '%s: %s' % (ADDON_NAME, txt)
else:
if isinstance(txt, str):
txt = txt.decode('utf-8')
message = (u'%s: %s' % (ADDON_NAME, txt)).encode('utf-8') # pylint: disable=redundant-u-string-prefix
xbmc.log(msg=message, level=xbmc.LOGDEBUG)
def notification(heading, message, icon=None, time=15000, sound=True):
""" Create a notification
:param heading: notification heading
:type heading: str
:param message: notification message
:type message: str
:param icon: path and filename for the notification icon
:type icon: str
:param time: time to display notification
:type time: int
:param sound: is notification audible
:type sound: bool
"""
if not icon:
icon = ICON
xbmcgui.Dialog().notification(heading, message, icon, time, sound)
def get_password_from_user():
""" Prompt user to input password
:return: password
:rtype: str
"""
pwd = ''
keyboard = xbmc.Keyboard('', ADDON_NAME + ': ' + localise(32022), True)
keyboard.doModal()
if keyboard.isConfirmed():
pwd = keyboard.getText()
return pwd
def message_upgrade_success():
""" Upgrade success notification
"""
notification(ADDON_NAME, localise(32013))
def message_restart():
""" Prompt user to restart Kodi
"""
if dialog_yes_no(32014):
xbmc.executebuiltin('RestartApp')
def dialog_yes_no(line1=0, line2=0):
""" Prompt user with yes/no dialog
:param line1: string id for the first line of the dialog
:type line1: int
:param line2: string id for the second line of the dialog
:type line2: int
:return: users selection (yes / no)
:rtype: bool
"""
return xbmcgui.Dialog().yesno(ADDON_NAME, '[CR]'.join([localise(line1), localise(line2)]))
def upgrade_message(msg):
""" Prompt user with upgrade suggestion message
:param msg: string id for prompt message
:type msg: int
"""
wait_for_end_of_video()
if ADDON.getSetting('lastnotified_version') < ADDON_VERSION:
xbmcgui.Dialog().ok(
ADDON_NAME,
'[CR]'.join([localise(msg), localise(32001), localise(32002)])
)
else:
log('Already notified one time for upgrading.')
def upgrade_message2(version_installed, version_available, version_stable, old_version):
""" Prompt user with upgrade suggestion message
:param version_installed: currently installed version
:type version_installed: dict
:param version_available: available version
:type version_available: dict
:param version_stable: latest stable version
:type version_stable: dict
:param old_version: whether using an old version
:type old_version: bool / 'stable'
"""
# shorten releasecandidate to rc
if version_installed['tag'] == 'releasecandidate':
version_installed['tag'] = 'rc'
if version_available['tag'] == 'releasecandidate':
version_available['tag'] = 'rc'
# convert json-rpc result to strings for usage
msg_current = '%i.%i %s%s' % (version_installed['major'],
version_installed['minor'],
version_installed['tag'],
version_installed.get('tagversion', ''))
msg_available = version_available['major'] + '.' + version_available['minor'] + ' ' + \
version_available['tag'] + version_available.get('tagversion', '')
msg_stable = version_stable['major'] + '.' + version_stable['minor'] + ' ' + \
version_stable['tag'] + version_stable.get('tagversion', '')
msg = localise(32034) % (msg_current, msg_available)
wait_for_end_of_video()
# hack: convert current version number to stable string
# so users don't get notified again. remove in future
if ADDON.getSetting('lastnotified_version') == '0.1.24':
ADDON.setSetting('lastnotified_stable', msg_stable)
# Show different dialogs depending if there's a newer stable available.
# Also split them between xbmc and kodi notifications to reduce possible confusion.
# People will find out once they visit the website.
# For stable only notify once and when there's a newer stable available.
# Ignore any add-on updates as those only count for != stable
if old_version == 'stable' and ADDON.getSetting('lastnotified_stable') != msg_stable:
if xbmcaddon.Addon('xbmc.addon').getAddonInfo('version') < '13.9.0':
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32030), localise(32031)]))
else:
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32032), localise(32033)]))
ADDON.setSetting('lastnotified_stable', msg_stable)
elif old_version != 'stable' and ADDON.getSetting('lastnotified_version') != msg_available:
if xbmcaddon.Addon('xbmc.addon').getAddonInfo('version') < '13.9.0':
# point them to xbmc.org
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32035), localise(32031)]))
else:
# use kodi.tv
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32035), localise(32033)]))
ADDON.setSetting('lastnotified_version', msg_available)
else:
log('Already notified one time for upgrading.')
def abort_requested():
""" Kodi 13+ compatible xbmc.Monitor().abortRequested()
:return: whether abort requested
:rtype: bool
"""
if KODI_VERSION_MAJOR > 13:
return MONITOR.abortRequested()
return xbmc.abortRequested
def wait_for_abort(seconds):
""" Kodi 13+ compatible xbmc.Monitor().waitForAbort()
:param seconds: seconds to wait for abort
:type seconds: int / float
:return: whether abort was requested
:rtype: bool
"""
if KODI_VERSION_MAJOR > 13:
return MONITOR.waitForAbort(seconds)
for _ in range(0, seconds * 1000 / 200):
if xbmc.abortRequested:
return True
xbmc.sleep(200)
return False
def wait_for_end_of_video():
""" Wait for video playback to end
"""
# Don't show notify while watching a video
while xbmc.Player().isPlayingVideo() and not abort_requested():
if wait_for_abort(1):
# Abort was requested while waiting. We should exit
break
i = 0
while i < 10 and not abort_requested():
if wait_for_abort(1):
# Abort was requested while waiting. We should exit
break
i += 1
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import sys
import xbmc # pylint: disable=import-error
import xbmcaddon # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
try:
xbmc.translatePath = xbmcvfs.translatePath
except AttributeError:
pass
ADDON = xbmcaddon.Addon('service.xbmc.versioncheck')
ADDON_VERSION = ADDON.getAddonInfo('version')
ADDON_NAME = ADDON.getAddonInfo('name')
if sys.version_info[0] >= 3:
ADDON_PATH = ADDON.getAddonInfo('path')
ADDON_PROFILE = xbmc.translatePath(ADDON.getAddonInfo('profile'))
else:
ADDON_PATH = ADDON.getAddonInfo('path').decode('utf-8')
ADDON_PROFILE = xbmc.translatePath(ADDON.getAddonInfo('profile')).decode('utf-8')
ICON = ADDON.getAddonInfo('icon')
KODI_VERSION_MAJOR = int(xbmc.getInfoLabel('System.BuildVersion')[0:2])
MONITOR = xbmc.Monitor()
# Fixes unicode problems
def string_unicode(text, encoding='utf-8'):
""" Python 2/3 -> unicode/str
:param text: text to convert
:type text: unicode (py2) / str (py3) / bytes (py3)
:param encoding: text encoding
:type encoding: str
:return: converted text
:rtype: unicode (py2) / str (py3)
"""
try:
if sys.version_info[0] >= 3:
text = str(text)
else:
text = unicode(text, encoding) # pylint: disable=undefined-variable
except: # pylint: disable=bare-except
pass
return text
def normalize_string(text):
""" Normalize string
:param text: text to normalize
:type text: unicode (py2) / str (py3) / bytes (py3)
:return: normalized text
:rtype: unicode (py2) / str (py3)
"""
try:
text = unicodedata.normalize('NFKD', string_unicode(text)).encode('ascii', 'ignore') # pylint: disable=undefined-variable
except: # pylint: disable=bare-except
pass
return text
def localise(string_id):
""" Localise string id
:param string_id: id of the string to localise
:type string_id: int
:return: localised string
:rtype: unicode (py2) / str (py3)
"""
string = normalize_string(ADDON.getLocalizedString(string_id))
return string
def log(txt):
""" Log text at xbmc.LOGDEBUG level
:param txt: text to log
:type txt: str / unicode / bytes (py3)
"""
if sys.version_info[0] >= 3:
if isinstance(txt, bytes):
txt = txt.decode('utf-8')
message = '%s: %s' % (ADDON_NAME, txt)
else:
if isinstance(txt, str):
txt = txt.decode('utf-8')
message = (u'%s: %s' % (ADDON_NAME, txt)).encode('utf-8') # pylint: disable=redundant-u-string-prefix
xbmc.log(msg=message, level=xbmc.LOGDEBUG)
def notification(heading, message, icon=None, time=15000, sound=True):
""" Create a notification
:param heading: notification heading
:type heading: str
:param message: notification message
:type message: str
:param icon: path and filename for the notification icon
:type icon: str
:param time: time to display notification
:type time: int
:param sound: is notification audible
:type sound: bool
"""
if not icon:
icon = ICON
xbmcgui.Dialog().notification(heading, message, icon, time, sound)
def get_password_from_user():
""" Prompt user to input password
:return: password
:rtype: str
"""
pwd = ''
keyboard = xbmc.Keyboard('', ADDON_NAME + ': ' + localise(32022), True)
keyboard.doModal()
if keyboard.isConfirmed():
pwd = keyboard.getText()
return pwd
def message_upgrade_success():
""" Upgrade success notification
"""
notification(ADDON_NAME, localise(32013))
def message_restart():
""" Prompt user to restart Kodi
"""
if dialog_yes_no(32014):
xbmc.executebuiltin('RestartApp')
def dialog_yes_no(line1=0, line2=0):
""" Prompt user with yes/no dialog
:param line1: string id for the first line of the dialog
:type line1: int
:param line2: string id for the second line of the dialog
:type line2: int
:return: users selection (yes / no)
:rtype: bool
"""
return xbmcgui.Dialog().yesno(ADDON_NAME, '[CR]'.join([localise(line1), localise(line2)]))
def upgrade_message(msg):
""" Prompt user with upgrade suggestion message
:param msg: string id for prompt message
:type msg: int
"""
wait_for_end_of_video()
if ADDON.getSetting('lastnotified_version') < ADDON_VERSION:
xbmcgui.Dialog().ok(
ADDON_NAME,
'[CR]'.join([localise(msg), localise(32001), localise(32002)])
)
else:
log('Already notified one time for upgrading.')
def upgrade_message2(version_installed, version_available, version_stable, old_version):
""" Prompt user with upgrade suggestion message
:param version_installed: currently installed version
:type version_installed: dict
:param version_available: available version
:type version_available: dict
:param version_stable: latest stable version
:type version_stable: dict
:param old_version: whether using an old version
:type old_version: bool / 'stable'
"""
# shorten releasecandidate to rc
if version_installed['tag'] == 'releasecandidate':
version_installed['tag'] = 'rc'
if version_available['tag'] == 'releasecandidate':
version_available['tag'] = 'rc'
# convert json-rpc result to strings for usage
msg_current = '%i.%i %s%s' % (version_installed['major'],
version_installed['minor'],
version_installed['tag'],
version_installed.get('tagversion', ''))
msg_available = version_available['major'] + '.' + version_available['minor'] + ' ' + \
version_available['tag'] + version_available.get('tagversion', '')
msg_stable = version_stable['major'] + '.' + version_stable['minor'] + ' ' + \
version_stable['tag'] + version_stable.get('tagversion', '')
msg = localise(32034) % (msg_current, msg_available)
wait_for_end_of_video()
# hack: convert current version number to stable string
# so users don't get notified again. remove in future
if ADDON.getSetting('lastnotified_version') == '0.1.24':
ADDON.setSetting('lastnotified_stable', msg_stable)
# Show different dialogs depending if there's a newer stable available.
# Also split them between xbmc and kodi notifications to reduce possible confusion.
# People will find out once they visit the website.
# For stable only notify once and when there's a newer stable available.
# Ignore any add-on updates as those only count for != stable
if old_version == 'stable' and ADDON.getSetting('lastnotified_stable') != msg_stable:
if xbmcaddon.Addon('xbmc.addon').getAddonInfo('version') < '13.9.0':
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32030), localise(32031)]))
else:
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32032), localise(32033)]))
ADDON.setSetting('lastnotified_stable', msg_stable)
elif old_version != 'stable' and ADDON.getSetting('lastnotified_version') != msg_available:
if xbmcaddon.Addon('xbmc.addon').getAddonInfo('version') < '13.9.0':
# point them to xbmc.org
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32035), localise(32031)]))
else:
# use kodi.tv
xbmcgui.Dialog().ok(ADDON_NAME, '[CR]'.join([msg, localise(32035), localise(32033)]))
ADDON.setSetting('lastnotified_version', msg_available)
else:
log('Already notified one time for upgrading.')
def abort_requested():
""" Kodi 13+ compatible xbmc.Monitor().abortRequested()
:return: whether abort requested
:rtype: bool
"""
if KODI_VERSION_MAJOR > 13:
return MONITOR.abortRequested()
return xbmc.abortRequested
def wait_for_abort(seconds):
""" Kodi 13+ compatible xbmc.Monitor().waitForAbort()
:param seconds: seconds to wait for abort
:type seconds: int / float
:return: whether abort was requested
:rtype: bool
"""
if KODI_VERSION_MAJOR > 13:
return MONITOR.waitForAbort(seconds)
for _ in range(0, seconds * 1000 / 200):
if xbmc.abortRequested:
return True
xbmc.sleep(200)
return False
def wait_for_end_of_video():
""" Wait for video playback to end
"""
# Don't show notify while watching a video
while xbmc.Player().isPlayingVideo() and not abort_requested():
if wait_for_abort(1):
# Abort was requested while waiting. We should exit
break
i = 0
while i < 10 and not abort_requested():
if wait_for_abort(1):
# Abort was requested while waiting. We should exit
break
i += 1

View File

@ -1,95 +1,95 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import get_password_from_user
from .common import log
class Handler:
""" Base handler class for apt_daemon_handler, and shell_handler_apt
"""
def __init__(self):
self._pwd = ''
self._update = True
@property
def pwd(self):
""" password property
:return: password
:rtype: str
"""
return self._pwd
@pwd.setter
def pwd(self, value):
""" password setter
:param value: password
:type value: str
"""
self._pwd = value
@property
def update(self):
""" update apt-cache property
:return: whether to update apt-cache or not when checking for upgrades
:rtype: bool
"""
return self._update
@update.setter
def update(self, value):
""" update apt-cache setter
:param value: whether to update apt-cache or not when checking for upgrades
:type value: bool
"""
self._update = value
def _check_versions(self, package):
raise NotImplementedError
def check_upgrade_available(self, package):
""" Check if package upgrade is available
:param package: package to check for upgrade availability
:type package: str
:return: whether an upgrade exists for the provided package
:rtype: bool
"""
installed, candidate = self._check_versions(package)
if installed and candidate:
if installed != candidate:
log('Version installed %s' % installed)
log('Version available %s' % candidate)
return True
log('Already on newest version')
return False
if not installed:
log('No installed package found')
return False
def _get_password(self):
""" Get password, ask user for password if not known
:return: password
:rtype: str
"""
if not self.pwd:
self.pwd = get_password_from_user()
return self.pwd
# -*- coding: utf-8 -*-
"""
Copyright (C) 2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import get_password_from_user
from .common import log
class Handler:
""" Base handler class for apt_daemon_handler, and shell_handler_apt
"""
def __init__(self):
self._pwd = ''
self._update = True
@property
def pwd(self):
""" password property
:return: password
:rtype: str
"""
return self._pwd
@pwd.setter
def pwd(self, value):
""" password setter
:param value: password
:type value: str
"""
self._pwd = value
@property
def update(self):
""" update apt-cache property
:return: whether to update apt-cache or not when checking for upgrades
:rtype: bool
"""
return self._update
@update.setter
def update(self, value):
""" update apt-cache setter
:param value: whether to update apt-cache or not when checking for upgrades
:type value: bool
"""
self._update = value
def _check_versions(self, package):
raise NotImplementedError
def check_upgrade_available(self, package):
""" Check if package upgrade is available
:param package: package to check for upgrade availability
:type package: str
:return: whether an upgrade exists for the provided package
:rtype: bool
"""
installed, candidate = self._check_versions(package)
if installed and candidate:
if installed != candidate:
log('Version installed %s' % installed)
log('Version available %s' % candidate)
return True
log('Already on newest version')
return False
if not installed:
log('No installed package found')
return False
def _get_password(self):
""" Get password, ask user for password if not known
:return: password
:rtype: str
"""
if not self.pwd:
self.pwd = get_password_from_user()
return self.pwd

View File

@ -1,67 +1,67 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from contextlib import closing
import json
import os
import sys
import xbmc # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
from .common import ADDON_PATH
def get_installed_version():
""" Retrieve the currently installed version
:return: currently installed version
:rtype: dict
"""
query = {
"jsonrpc": "2.0",
"method": "Application.GetProperties",
"params": {
"properties": ["version", "name"]
},
"id": 1
}
json_query = xbmc.executeJSONRPC(json.dumps(query))
if sys.version_info[0] >= 3:
json_query = str(json_query)
else:
json_query = unicode(json_query, 'utf-8', errors='ignore') # pylint: disable=undefined-variable
json_query = json.loads(json_query)
version_installed = []
if 'result' in json_query and 'version' in json_query['result']:
version_installed = json_query['result']['version']
return version_installed
def get_version_file_list():
""" Retrieve version lists from supplied version file (resources/versions.txt)
:return: all provided versions
:rtype: dict
"""
version_file = os.path.join(ADDON_PATH, 'resources/versions.txt')
with closing(xbmcvfs.File(version_file)) as open_file:
data = open_file.read()
if sys.version_info[0] >= 3:
version_query = str(data)
else:
version_query = unicode(data, 'utf-8', errors='ignore') # pylint: disable=undefined-variable
version_query = json.loads(version_query)
return version_query
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from contextlib import closing
import json
import os
import sys
import xbmc # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
from .common import ADDON_PATH
def get_installed_version():
""" Retrieve the currently installed version
:return: currently installed version
:rtype: dict
"""
query = {
"jsonrpc": "2.0",
"method": "Application.GetProperties",
"params": {
"properties": ["version", "name"]
},
"id": 1
}
json_query = xbmc.executeJSONRPC(json.dumps(query))
if sys.version_info[0] >= 3:
json_query = str(json_query)
else:
json_query = unicode(json_query, 'utf-8', errors='ignore') # pylint: disable=undefined-variable
json_query = json.loads(json_query)
version_installed = []
if 'result' in json_query and 'version' in json_query['result']:
version_installed = json_query['result']['version']
return version_installed
def get_version_file_list():
""" Retrieve version lists from supplied version file (resources/versions.txt)
:return: all provided versions
:rtype: dict
"""
version_file = os.path.join(ADDON_PATH, 'resources/versions.txt')
with closing(xbmcvfs.File(version_file)) as open_file:
data = open_file.read()
if sys.version_info[0] >= 3:
version_query = str(data)
else:
version_query = unicode(data, 'utf-8', errors='ignore') # pylint: disable=undefined-variable
version_query = json.loads(version_query)
return version_query

View File

@ -1,165 +1,165 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import platform
import sys
import xbmc # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
from .common import ADDON
from .common import ADDON_NAME
from .common import ADDON_VERSION
from .common import dialog_yes_no
from .common import localise
from .common import log
from .common import wait_for_abort
from .common import message_restart
from .common import message_upgrade_success
from .common import upgrade_message
from .common import upgrade_message2
from .json_interface import get_version_file_list
from .json_interface import get_installed_version
from .versions import compare_version
DISTRIBUTION = ''
if sys.platform.startswith('linux'):
if sys.version_info[0] == 3 and sys.version_info[1] >= 8:
try:
from .distro import distro
DISTRIBUTION = distro.linux_distribution(full_distribution_name=False)[0].lower()
except (AttributeError, ImportError):
DISTRIBUTION = ''
else:
DISTRIBUTION = platform.linux_distribution(full_distribution_name=0)[0].lower() # pylint: disable=no-member
if not DISTRIBUTION:
DISTRIBUTION = platform.uname()[0].lower()
def _version_check():
""" Check versions (non-linux)
:return: old, current, available, and stable versions
:rtype: bool / 'stable', dict, dict, dict
"""
# retrieve version_lists from supplied version file
version_list = get_version_file_list()
# retrieve version installed
version_installed = get_installed_version()
# compare installed and available
old_version, version_installed, version_available, version_stable = \
compare_version(version_installed, version_list)
return old_version, version_installed, version_available, version_stable
def _version_check_linux(packages):
""" Check package version on linux
:param packages: list of packages to check
:type packages: list of str
"""
if DISTRIBUTION in ['ubuntu', 'debian', 'linuxmint']:
try:
# try aptdaemon first
# pylint: disable=import-outside-toplevel
from .apt_daemon_handler import AptDaemonHandler
handler = AptDaemonHandler()
except: # pylint: disable=bare-except
# fallback to shell
# since we need the user password, ask to check for new version first
# pylint: disable=import-outside-toplevel
from .shell_handler_apt import ShellHandlerApt
handler = ShellHandlerApt(use_sudo=True)
if dialog_yes_no(32015):
pass
elif dialog_yes_no(32009, 32010):
log('disabling addon by user request')
ADDON.setSetting('versioncheck_enable', 'false')
return
if handler:
if handler.check_upgrade_available(packages[0]):
if upgrade_message(32012):
if ADDON.getSetting('upgrade_system') == 'false':
result = handler.upgrade_package(packages[0])
else:
result = handler.upgrade_system()
if result:
message_upgrade_success()
message_restart()
else:
log('Error during upgrade')
return
log('No upgrade available')
return
log('Error: no handler found')
return
log('Unsupported platform %s' % DISTRIBUTION)
sys.exit(0)
def _check_cryptography():
""" Check for cryptography package, and version
Python cryptography < 1.7 (still shipped with Ubuntu 16.04) has issues with
pyOpenSSL integration, leading to all sorts of weird bugs - check here to save
on some troubleshooting. This check may be removed in the future (when switching
to Python3?)
See https://github.com/pyca/pyopenssl/issues/542
"""
try:
import cryptography # pylint: disable=import-outside-toplevel
ver = cryptography.__version__
except ImportError:
# If the module is not found - no problem
return
ver_parts = list(map(int, ver.split('.')))
if len(ver_parts) < 2 or ver_parts[0] < 1 or (ver_parts[0] == 1 and ver_parts[1] < 7):
log('Python cryptography module version %s is too old, at least version 1.7 needed' % ver)
xbmcgui.Dialog().ok(
ADDON_NAME,
'[CR]'.join([localise(32040) % ver, localise(32041), localise(32042)])
)
def run():
""" Service entry-point
"""
_check_cryptography()
if ADDON.getSetting('versioncheck_enable') == 'false':
log('Disabled')
else:
log('Version %s started' % ADDON_VERSION)
if wait_for_abort(5):
sys.exit(0)
if (xbmc.getCondVisibility('System.Platform.Linux') and
ADDON.getSetting('upgrade_apt') == 'true'):
_version_check_linux(['kodi'])
else:
old_version, version_installed, version_available, version_stable = _version_check()
if old_version:
upgrade_message2(version_installed, version_available, version_stable, old_version)
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import platform
import sys
import xbmc # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
from .common import ADDON
from .common import ADDON_NAME
from .common import ADDON_VERSION
from .common import dialog_yes_no
from .common import localise
from .common import log
from .common import wait_for_abort
from .common import message_restart
from .common import message_upgrade_success
from .common import upgrade_message
from .common import upgrade_message2
from .json_interface import get_version_file_list
from .json_interface import get_installed_version
from .versions import compare_version
DISTRIBUTION = ''
if sys.platform.startswith('linux'):
if sys.version_info[0] == 3 and sys.version_info[1] >= 8:
try:
from .distro import distro
DISTRIBUTION = distro.linux_distribution(full_distribution_name=False)[0].lower()
except (AttributeError, ImportError):
DISTRIBUTION = ''
else:
DISTRIBUTION = platform.linux_distribution(full_distribution_name=0)[0].lower() # pylint: disable=no-member
if not DISTRIBUTION:
DISTRIBUTION = platform.uname()[0].lower()
def _version_check():
""" Check versions (non-linux)
:return: old, current, available, and stable versions
:rtype: bool / 'stable', dict, dict, dict
"""
# retrieve version_lists from supplied version file
version_list = get_version_file_list()
# retrieve version installed
version_installed = get_installed_version()
# compare installed and available
old_version, version_installed, version_available, version_stable = \
compare_version(version_installed, version_list)
return old_version, version_installed, version_available, version_stable
def _version_check_linux(packages):
""" Check package version on linux
:param packages: list of packages to check
:type packages: list of str
"""
if DISTRIBUTION in ['ubuntu', 'debian', 'linuxmint']:
try:
# try aptdaemon first
# pylint: disable=import-outside-toplevel
from .apt_daemon_handler import AptDaemonHandler
handler = AptDaemonHandler()
except: # pylint: disable=bare-except
# fallback to shell
# since we need the user password, ask to check for new version first
# pylint: disable=import-outside-toplevel
from .shell_handler_apt import ShellHandlerApt
handler = ShellHandlerApt(use_sudo=True)
if dialog_yes_no(32015):
pass
elif dialog_yes_no(32009, 32010):
log('disabling addon by user request')
ADDON.setSetting('versioncheck_enable', 'false')
return
if handler:
if handler.check_upgrade_available(packages[0]):
if upgrade_message(32012):
if ADDON.getSetting('upgrade_system') == 'false':
result = handler.upgrade_package(packages[0])
else:
result = handler.upgrade_system()
if result:
message_upgrade_success()
message_restart()
else:
log('Error during upgrade')
return
log('No upgrade available')
return
log('Error: no handler found')
return
log('Unsupported platform %s' % DISTRIBUTION)
sys.exit(0)
def _check_cryptography():
""" Check for cryptography package, and version
Python cryptography < 1.7 (still shipped with Ubuntu 16.04) has issues with
pyOpenSSL integration, leading to all sorts of weird bugs - check here to save
on some troubleshooting. This check may be removed in the future (when switching
to Python3?)
See https://github.com/pyca/pyopenssl/issues/542
"""
try:
import cryptography # pylint: disable=import-outside-toplevel
ver = cryptography.__version__
except ImportError:
# If the module is not found - no problem
return
ver_parts = list(map(int, ver.split('.')))
if len(ver_parts) < 2 or ver_parts[0] < 1 or (ver_parts[0] == 1 and ver_parts[1] < 7):
log('Python cryptography module version %s is too old, at least version 1.7 needed' % ver)
xbmcgui.Dialog().ok(
ADDON_NAME,
'[CR]'.join([localise(32040) % ver, localise(32041), localise(32042)])
)
def run():
""" Service entry-point
"""
_check_cryptography()
if ADDON.getSetting('versioncheck_enable') == 'false':
log('Disabled')
else:
log('Version %s started' % ADDON_VERSION)
if wait_for_abort(5):
sys.exit(0)
if (xbmc.getCondVisibility('System.Platform.Linux') and
ADDON.getSetting('upgrade_apt') == 'true'):
_version_check_linux(['kodi'])
else:
old_version, version_installed, version_available, version_stable = _version_check()
if old_version:
upgrade_message2(version_installed, version_available, version_stable, old_version)

View File

@ -1,132 +1,132 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import sys
from .common import log
from .handler import Handler
try:
from subprocess import check_output
except ImportError:
check_output = None
log('ImportError: subprocess')
class ShellHandlerApt(Handler):
""" Apt shell handler
"""
def __init__(self, use_sudo=False):
Handler.__init__(self)
self.sudo = use_sudo
self._update = False
installed, _ = self._check_versions('kodi')
if not installed:
# there is no package installed via repo, so we exit here
log('No installed package found, exiting')
sys.exit(0)
self._update = True
def _check_versions(self, package):
""" Check apt package versions
:param package: package to check
:type package: str
:return: installed version, candidate version
:rtype: str, str / False, False
"""
_cmd = 'apt-cache policy ' + package
if self.update and not self._update_cache():
return False, False
try:
result = check_output([_cmd], shell=True).split('\n')
except Exception as error: # pylint: disable=broad-except
log('ShellHandlerApt: exception while executing shell command %s: %s' % (_cmd, error))
return False, False
if result[0].replace(':', '') == package:
installed = result[1].split()[1]
candidate = result[2].split()[1]
if installed == '(none)':
installed = False
if candidate == '(none)':
candidate = False
return installed, candidate
log('ShellHandlerApt: error during version check')
return False, False
def _update_cache(self):
""" Update apt cache
:return: success of updating apt cache
:rtype: bool
"""
_cmd = 'apt-get update'
try:
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True
def upgrade_package(self, package):
""" Upgrade apt package
:param package: package to upgrade
:type package: str
:return: success of apt package upgrade
:rtype: bool
"""
_cmd = 'apt-get install -y ' + package
try:
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
log('Upgrade successful')
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True
def upgrade_system(self):
""" Upgrade system
:return: success of system upgrade
:rtype: bool
"""
_cmd = 'apt-get upgrade -y'
try:
log('Upgrading system')
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
import sys
from .common import log
from .handler import Handler
try:
from subprocess import check_output
except ImportError:
check_output = None
log('ImportError: subprocess')
class ShellHandlerApt(Handler):
""" Apt shell handler
"""
def __init__(self, use_sudo=False):
Handler.__init__(self)
self.sudo = use_sudo
self._update = False
installed, _ = self._check_versions('kodi')
if not installed:
# there is no package installed via repo, so we exit here
log('No installed package found, exiting')
sys.exit(0)
self._update = True
def _check_versions(self, package):
""" Check apt package versions
:param package: package to check
:type package: str
:return: installed version, candidate version
:rtype: str, str / False, False
"""
_cmd = 'apt-cache policy ' + package
if self.update and not self._update_cache():
return False, False
try:
result = check_output([_cmd], shell=True).split('\n')
except Exception as error: # pylint: disable=broad-except
log('ShellHandlerApt: exception while executing shell command %s: %s' % (_cmd, error))
return False, False
if result[0].replace(':', '') == package:
installed = result[1].split()[1]
candidate = result[2].split()[1]
if installed == '(none)':
installed = False
if candidate == '(none)':
candidate = False
return installed, candidate
log('ShellHandlerApt: error during version check')
return False, False
def _update_cache(self):
""" Update apt cache
:return: success of updating apt cache
:rtype: bool
"""
_cmd = 'apt-get update'
try:
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True
def upgrade_package(self, package):
""" Upgrade apt package
:param package: package to upgrade
:type package: str
:return: success of apt package upgrade
:rtype: bool
"""
_cmd = 'apt-get install -y ' + package
try:
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
log('Upgrade successful')
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True
def upgrade_system(self):
""" Upgrade system
:return: success of system upgrade
:rtype: bool
"""
_cmd = 'apt-get upgrade -y'
try:
log('Upgrading system')
if self.sudo:
_ = check_output('echo \'%s\' | sudo -S %s' %
(self._get_password(), _cmd), shell=True)
else:
_ = check_output(_cmd.split())
except Exception as error: # pylint: disable=broad-except
log('Exception while executing shell command %s: %s' % (_cmd, error))
return False
return True

View File

@ -1,216 +1,216 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import log
def compare_version(version_installed, version_list):
""" Compare the installed version against the provided version list
:param version_installed: currently installed version
:type version_installed: dict
:param version_list: provided versions to compare against
:type version_list: dict
:return: old, current, available, and stable versions
:rtype: bool / 'stable', dict, dict, dict
"""
# Create separate version lists
version_list_stable = version_list['releases']['stable']
version_list_rc = version_list['releases']['releasecandidate']
version_list_beta = version_list['releases']['beta']
version_list_alpha = version_list['releases']['alpha']
# version_list_prealpha = version_list['releases']['prealpha']
stable_version = version_list_stable[0]
rc_version = version_list_rc[0]
beta_version = version_list_beta[0]
alpha_version = version_list_alpha[0]
log('Version installed %s' % version_installed)
# Check to upgrade to newest available stable version
# check on smaller major version. Smaller version than available always notify
# check for stable versions
old_version, version_available = _check_for_stable_version(version_installed, stable_version)
if not old_version:
# Already skipped a possible newer stable build. Let's continue with non stable builds.
# Check also 'old version' hasn't been set to 'stable' or true by previous checks because
# if so, those part need to be skipped
old_version, version_available = _check_for_rc_version(version_installed,
rc_version, beta_version)
if not old_version:
# check for beta builds
old_version, version_available = _check_for_beta_version(version_installed, beta_version)
if not old_version:
# check for alpha builds
old_version, version_available = _check_for_alpha_version(version_installed, alpha_version)
return old_version, version_installed, version_available, stable_version
def _check_for_stable_version(version_installed, stable_version):
""" Compare the installed version against the latest stable version
:param version_installed: currently installed version
:type version_installed: dict
:param stable_version: latest stable version
:type stable_version: dict
:return: whether using an old version, and available version if newer stable version available
:rtype: bool / 'stable', dict
"""
# check if installed major version is smaller than available major stable
# here we don't care if running non stable
old_version = False
version_available = {}
if version_installed['major'] < int(stable_version['major']):
version_available = stable_version
old_version = 'stable'
log('Version available %s' % stable_version)
log('You are running an older version')
# check if installed major version is equal than available major stable
# however also check on minor version and still don't care about non stable
elif version_installed['major'] == int(stable_version['major']):
if version_installed['minor'] < int(stable_version['minor']):
version_available = stable_version
old_version = 'stable'
log('Version available %s' % stable_version)
log('You are running an older minor version')
# check for <= minor !stable
elif version_installed['tag'] != 'stable' and \
version_installed['minor'] <= int(stable_version['minor']):
version_available = stable_version
old_version = True
log('Version available %s' % stable_version)
log('You are running an older non stable minor version')
else:
log('Version available %s' % stable_version)
log('There is no newer stable available')
return old_version, version_available
def _check_for_rc_version(version_installed, rc_version, beta_version):
""" Compare the installed version against the latest RC version
:param version_installed: currently installed version
:type version_installed: dict
:param rc_version: latest rc version
:type rc_version: dict
:param beta_version: latest beta version
:type beta_version: dict
:return: whether using an old version, and available version if newer rc version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for RC builds
if version_installed['tag'] in ['releasecandidate']:
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0rc3 is newer than: 14.0rc1, 14.0b9, 14.0a15
if version_installed['major'] <= int(rc_version['major']):
if version_installed['minor'] <= int(rc_version['minor']):
if version_installed.get('tagversion', '') < rc_version['tagversion']:
version_available = rc_version
old_version = True
log('Version available %s' % rc_version)
log('You are running an older RC version')
# now check if installed !=rc
elif version_installed['tag'] in ['beta', 'alpha', 'prealpha']:
if version_installed['major'] <= int(rc_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
version_available = rc_version
old_version = True
log('Version available %s' % rc_version)
log('You are running an older non RC version')
return old_version, version_available
def _check_for_beta_version(version_installed, beta_version):
""" Compare the installed version against the latest beta version
:param version_installed: currently installed version
:type version_installed: dict
:param beta_version: latest beta version
:type beta_version: dict
:return: whether using an old version, and available version if newer beta version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for beta builds
if not old_version and version_installed['tag'] == 'beta':
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0b3 is newer than: 14.0b1, 14.0a15
if version_installed['major'] <= int(beta_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
if version_installed.get('tagversion', '') < beta_version['tagversion']:
version_available = beta_version
old_version = True
log('Version available %s' % beta_version)
log('You are running an older beta version')
# now check if installed !=beta
elif not old_version and version_installed['tag'] in ['alpha', 'prealpha']:
if version_installed['major'] <= int(beta_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
version_available = beta_version
old_version = True
log('Version available %s' % beta_version)
log('You are running an older non beta version')
return old_version, version_available
def _check_for_alpha_version(version_installed, alpha_version):
""" Compare the installed version against the latest alpha version
:param version_installed: currently installed version
:type version_installed: dict
:param alpha_version: latest alpha version
:type alpha_version: dict
:return: whether using an old version, and available version if newer alpha version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for alpha builds and older
if version_installed['tag'] == 'alpha':
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0a3 is newer than: 14.0a1 or pre-alpha
if version_installed['major'] <= int(alpha_version['major']):
if version_installed['minor'] <= int(alpha_version['minor']):
if version_installed.get('tagversion', '') < alpha_version['tagversion']:
version_available = alpha_version
old_version = True
log('Version available %s' % alpha_version)
log('You are running an older alpha version')
# now check if installed !=alpha
elif version_installed['tag'] in ['prealpha']:
if version_installed['major'] <= int(alpha_version['major']):
if version_installed['minor'] <= int(alpha_version['minor']):
version_available = alpha_version
old_version = True
log('Version available %s' % alpha_version)
log('You are running an older non alpha version')
return old_version, version_available
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from .common import log
def compare_version(version_installed, version_list):
""" Compare the installed version against the provided version list
:param version_installed: currently installed version
:type version_installed: dict
:param version_list: provided versions to compare against
:type version_list: dict
:return: old, current, available, and stable versions
:rtype: bool / 'stable', dict, dict, dict
"""
# Create separate version lists
version_list_stable = version_list['releases']['stable']
version_list_rc = version_list['releases']['releasecandidate']
version_list_beta = version_list['releases']['beta']
version_list_alpha = version_list['releases']['alpha']
# version_list_prealpha = version_list['releases']['prealpha']
stable_version = version_list_stable[0]
rc_version = version_list_rc[0]
beta_version = version_list_beta[0]
alpha_version = version_list_alpha[0]
log('Version installed %s' % version_installed)
# Check to upgrade to newest available stable version
# check on smaller major version. Smaller version than available always notify
# check for stable versions
old_version, version_available = _check_for_stable_version(version_installed, stable_version)
if not old_version:
# Already skipped a possible newer stable build. Let's continue with non stable builds.
# Check also 'old version' hasn't been set to 'stable' or true by previous checks because
# if so, those part need to be skipped
old_version, version_available = _check_for_rc_version(version_installed,
rc_version, beta_version)
if not old_version:
# check for beta builds
old_version, version_available = _check_for_beta_version(version_installed, beta_version)
if not old_version:
# check for alpha builds
old_version, version_available = _check_for_alpha_version(version_installed, alpha_version)
return old_version, version_installed, version_available, stable_version
def _check_for_stable_version(version_installed, stable_version):
""" Compare the installed version against the latest stable version
:param version_installed: currently installed version
:type version_installed: dict
:param stable_version: latest stable version
:type stable_version: dict
:return: whether using an old version, and available version if newer stable version available
:rtype: bool / 'stable', dict
"""
# check if installed major version is smaller than available major stable
# here we don't care if running non stable
old_version = False
version_available = {}
if version_installed['major'] < int(stable_version['major']):
version_available = stable_version
old_version = 'stable'
log('Version available %s' % stable_version)
log('You are running an older version')
# check if installed major version is equal than available major stable
# however also check on minor version and still don't care about non stable
elif version_installed['major'] == int(stable_version['major']):
if version_installed['minor'] < int(stable_version['minor']):
version_available = stable_version
old_version = 'stable'
log('Version available %s' % stable_version)
log('You are running an older minor version')
# check for <= minor !stable
elif version_installed['tag'] != 'stable' and \
version_installed['minor'] <= int(stable_version['minor']):
version_available = stable_version
old_version = True
log('Version available %s' % stable_version)
log('You are running an older non stable minor version')
else:
log('Version available %s' % stable_version)
log('There is no newer stable available')
return old_version, version_available
def _check_for_rc_version(version_installed, rc_version, beta_version):
""" Compare the installed version against the latest RC version
:param version_installed: currently installed version
:type version_installed: dict
:param rc_version: latest rc version
:type rc_version: dict
:param beta_version: latest beta version
:type beta_version: dict
:return: whether using an old version, and available version if newer rc version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for RC builds
if version_installed['tag'] in ['releasecandidate']:
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0rc3 is newer than: 14.0rc1, 14.0b9, 14.0a15
if version_installed['major'] <= int(rc_version['major']):
if version_installed['minor'] <= int(rc_version['minor']):
if version_installed.get('tagversion', '') < rc_version['tagversion']:
version_available = rc_version
old_version = True
log('Version available %s' % rc_version)
log('You are running an older RC version')
# now check if installed !=rc
elif version_installed['tag'] in ['beta', 'alpha', 'prealpha']:
if version_installed['major'] <= int(rc_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
version_available = rc_version
old_version = True
log('Version available %s' % rc_version)
log('You are running an older non RC version')
return old_version, version_available
def _check_for_beta_version(version_installed, beta_version):
""" Compare the installed version against the latest beta version
:param version_installed: currently installed version
:type version_installed: dict
:param beta_version: latest beta version
:type beta_version: dict
:return: whether using an old version, and available version if newer beta version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for beta builds
if not old_version and version_installed['tag'] == 'beta':
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0b3 is newer than: 14.0b1, 14.0a15
if version_installed['major'] <= int(beta_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
if version_installed.get('tagversion', '') < beta_version['tagversion']:
version_available = beta_version
old_version = True
log('Version available %s' % beta_version)
log('You are running an older beta version')
# now check if installed !=beta
elif not old_version and version_installed['tag'] in ['alpha', 'prealpha']:
if version_installed['major'] <= int(beta_version['major']):
if version_installed['minor'] <= int(beta_version['minor']):
version_available = beta_version
old_version = True
log('Version available %s' % beta_version)
log('You are running an older non beta version')
return old_version, version_available
def _check_for_alpha_version(version_installed, alpha_version):
""" Compare the installed version against the latest alpha version
:param version_installed: currently installed version
:type version_installed: dict
:param alpha_version: latest alpha version
:type alpha_version: dict
:return: whether using an old version, and available version if newer alpha version available
:rtype: bool, dict
"""
old_version = False
version_available = {}
# check for alpha builds and older
if version_installed['tag'] == 'alpha':
# check if you are using a RC build lower than current available RC
# then check if you are using a beta/alpha lower than current available RC
# 14.0a3 is newer than: 14.0a1 or pre-alpha
if version_installed['major'] <= int(alpha_version['major']):
if version_installed['minor'] <= int(alpha_version['minor']):
if version_installed.get('tagversion', '') < alpha_version['tagversion']:
version_available = alpha_version
old_version = True
log('Version available %s' % alpha_version)
log('You are running an older alpha version')
# now check if installed !=alpha
elif version_installed['tag'] in ['prealpha']:
if version_installed['major'] <= int(alpha_version['major']):
if version_installed['minor'] <= int(alpha_version['minor']):
version_available = alpha_version
old_version = True
log('Version available %s' % alpha_version)
log('You are running an older non alpha version')
return old_version, version_available

View File

@ -1,159 +1,159 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (C) 2011-2013 Martijn Kaijser
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from contextlib import closing
import os
import sys
import xbmc # pylint: disable=import-error
import xbmcaddon # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
_ADDON = xbmcaddon.Addon('service.xbmc.versioncheck')
_ADDON_NAME = _ADDON.getAddonInfo('name')
if sys.version_info[0] >= 3:
_ADDON_PATH = _ADDON.getAddonInfo('path')
else:
_ADDON_PATH = _ADDON.getAddonInfo('path').decode('utf-8')
_ICON = _ADDON.getAddonInfo('icon')
class Viewer:
""" Show user a text viewer (WINDOW_DIALOG_TEXT_VIEWER)
Include the text file for the viewers body in the resources/ directory
usage:
script_path = os.path.join(_ADDON_PATH, 'resources', 'lib', 'version_check', 'viewer.py')
xbmc.executebuiltin('RunScript(%s,%s,%s)' % (script_path, 'Heading', 'notice.txt'))
:param heading: text viewer heading
:type heading: str
:param filename: filename to use for text viewers body
:type filename: str
"""
WINDOW = 10147
CONTROL_LABEL = 1
CONTROL_TEXTBOX = 5
def __init__(self, heading, filename):
self.heading = heading
self.filename = filename
# activate the text viewer window
xbmc.executebuiltin('ActivateWindow(%d)' % (self.WINDOW,))
# get window
self.window = xbmcgui.Window(self.WINDOW)
# give window time to initialize
xbmc.sleep(100)
# set controls
self.set_controls()
def set_controls(self):
""" Set the window controls
"""
# get text viewer body text
text = self.get_text()
# set heading
self.window.getControl(self.CONTROL_LABEL).setLabel('%s : %s' % (_ADDON_NAME,
self.heading,))
# set text
self.window.getControl(self.CONTROL_TEXTBOX).setText(text)
xbmc.sleep(2000)
def get_text(self):
""" Get the text viewers body text from self.filename
:return: contents of self.filename
:rtype: str
"""
try:
return self.read_file(self.filename)
except Exception as error: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(error), xbmc.LOGERROR)
return ''
@staticmethod
def read_file(filename):
""" Read the contents of the provided file, from
os.path.join(_ADDON_PATH, 'resources', filename)
:param filename: name of file to read
:type filename: str
:return: contents of the provided file
:rtype: str
"""
filename = os.path.join(_ADDON_PATH, 'resources', filename)
with closing(xbmcvfs.File(filename)) as open_file:
contents = open_file.read()
return contents
class WebBrowser:
""" Display url using the default browser
usage:
script_path = os.path.join(_ADDON_PATH, 'resources', 'lib', 'version_check', 'viewer.py')
xbmc.executebuiltin('RunScript(%s,%s,%s)' % (script_path, 'webbrowser', 'https://kodi.tv/'))
:param url: url to open
:type url: str
"""
def __init__(self, url):
self.url = url
try:
# notify user
self.notification(_ADDON_NAME, self.url)
xbmc.sleep(100)
# launch url
self.launch_url()
except Exception as error: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(error), xbmc.LOGERROR)
@staticmethod
def notification(heading, message, icon=None, time=15000, sound=True):
""" Create a notification
:param heading: notification heading
:type heading: str
:param message: notification message
:type message: str
:param icon: path and filename for the notification icon
:type icon: str
:param time: time to display notification
:type time: int
:param sound: is notification audible
:type sound: bool
"""
if not icon:
icon = _ICON
xbmcgui.Dialog().notification(heading, message, icon, time, sound)
def launch_url(self):
""" Open self.url in the default web browser
"""
import webbrowser # pylint: disable=import-outside-toplevel
webbrowser.open(self.url)
if __name__ == '__main__':
try:
if sys.argv[1] == 'webbrowser':
WebBrowser(sys.argv[2])
else:
Viewer(sys.argv[1], sys.argv[2])
except Exception as err: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(err), xbmc.LOGERROR)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright (C) 2011-2013 Martijn Kaijser
Copyright (C) 2013-2014 Team-XBMC
Copyright (C) 2014-2019 Team Kodi
This file is part of service.xbmc.versioncheck
SPDX-License-Identifier: GPL-3.0-or-later
See LICENSES/GPL-3.0-or-later.txt for more information.
"""
from contextlib import closing
import os
import sys
import xbmc # pylint: disable=import-error
import xbmcaddon # pylint: disable=import-error
import xbmcgui # pylint: disable=import-error
import xbmcvfs # pylint: disable=import-error
_ADDON = xbmcaddon.Addon('service.xbmc.versioncheck')
_ADDON_NAME = _ADDON.getAddonInfo('name')
if sys.version_info[0] >= 3:
_ADDON_PATH = _ADDON.getAddonInfo('path')
else:
_ADDON_PATH = _ADDON.getAddonInfo('path').decode('utf-8')
_ICON = _ADDON.getAddonInfo('icon')
class Viewer:
""" Show user a text viewer (WINDOW_DIALOG_TEXT_VIEWER)
Include the text file for the viewers body in the resources/ directory
usage:
script_path = os.path.join(_ADDON_PATH, 'resources', 'lib', 'version_check', 'viewer.py')
xbmc.executebuiltin('RunScript(%s,%s,%s)' % (script_path, 'Heading', 'notice.txt'))
:param heading: text viewer heading
:type heading: str
:param filename: filename to use for text viewers body
:type filename: str
"""
WINDOW = 10147
CONTROL_LABEL = 1
CONTROL_TEXTBOX = 5
def __init__(self, heading, filename):
self.heading = heading
self.filename = filename
# activate the text viewer window
xbmc.executebuiltin('ActivateWindow(%d)' % (self.WINDOW,))
# get window
self.window = xbmcgui.Window(self.WINDOW)
# give window time to initialize
xbmc.sleep(100)
# set controls
self.set_controls()
def set_controls(self):
""" Set the window controls
"""
# get text viewer body text
text = self.get_text()
# set heading
self.window.getControl(self.CONTROL_LABEL).setLabel('%s : %s' % (_ADDON_NAME,
self.heading,))
# set text
self.window.getControl(self.CONTROL_TEXTBOX).setText(text)
xbmc.sleep(2000)
def get_text(self):
""" Get the text viewers body text from self.filename
:return: contents of self.filename
:rtype: str
"""
try:
return self.read_file(self.filename)
except Exception as error: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(error), xbmc.LOGERROR)
return ''
@staticmethod
def read_file(filename):
""" Read the contents of the provided file, from
os.path.join(_ADDON_PATH, 'resources', filename)
:param filename: name of file to read
:type filename: str
:return: contents of the provided file
:rtype: str
"""
filename = os.path.join(_ADDON_PATH, 'resources', filename)
with closing(xbmcvfs.File(filename)) as open_file:
contents = open_file.read()
return contents
class WebBrowser:
""" Display url using the default browser
usage:
script_path = os.path.join(_ADDON_PATH, 'resources', 'lib', 'version_check', 'viewer.py')
xbmc.executebuiltin('RunScript(%s,%s,%s)' % (script_path, 'webbrowser', 'https://kodi.tv/'))
:param url: url to open
:type url: str
"""
def __init__(self, url):
self.url = url
try:
# notify user
self.notification(_ADDON_NAME, self.url)
xbmc.sleep(100)
# launch url
self.launch_url()
except Exception as error: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(error), xbmc.LOGERROR)
@staticmethod
def notification(heading, message, icon=None, time=15000, sound=True):
""" Create a notification
:param heading: notification heading
:type heading: str
:param message: notification message
:type message: str
:param icon: path and filename for the notification icon
:type icon: str
:param time: time to display notification
:type time: int
:param sound: is notification audible
:type sound: bool
"""
if not icon:
icon = _ICON
xbmcgui.Dialog().notification(heading, message, icon, time, sound)
def launch_url(self):
""" Open self.url in the default web browser
"""
import webbrowser # pylint: disable=import-outside-toplevel
webbrowser.open(self.url)
if __name__ == '__main__':
try:
if sys.argv[1] == 'webbrowser':
WebBrowser(sys.argv[2])
else:
Viewer(sys.argv[1], sys.argv[2])
except Exception as err: # pylint: disable=broad-except
xbmc.log(_ADDON_NAME + ': ' + str(err), xbmc.LOGERROR)

View File

@ -1,11 +1,11 @@
If you run Kodi/XBMC standalone and/or do want to have password less upgrades, copy the file
10-allow-update.conf to /etc/polkit-1/localauthority/50-local.d/
Make sure to adjust the username if it is different from "kodi"
For this to work, you must have python-apt and python-aptdaemon installed:
sudo apt-get install python-apt python-aptdaemon
If those packages are not installed, this script will fallback to calling apt directly and ask you
for your password.
If you run Kodi/XBMC standalone and/or do want to have password less upgrades, copy the file
10-allow-update.conf to /etc/polkit-1/localauthority/50-local.d/
Make sure to adjust the username if it is different from "kodi"
For this to work, you must have python-apt and python-aptdaemon installed:
sudo apt-get install python-apt python-aptdaemon
If those packages are not installed, this script will fallback to calling apt directly and ask you
for your password.

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#a4c639" stroke-width=".27763"/>
<path d="m21.059 281.63c0-0.62897-0.50779-1.1406-1.1391-1.1406-0.63126 0-1.1421 0.50935-1.1421 1.1422v4.7769c0 0.62508 0.51165 1.1421 1.1445 1.1421 0.62818 0 1.1391-0.51705 1.1391-1.1421v-4.7846h-0.0079zm-12.929-0.92221 0.0032 7.4085c0 0.68298 0.54328 1.227 1.2139 1.227h0.82033v2.5312c0 0.63281 0.50933 1.1437 1.1344 1.1437 0.62509 0 1.1321-0.50932 1.1421-1.1328v-2.5312h1.538v2.5312c0 0.63511 0.50933 1.1444 1.1344 1.1444 0.63512 0 1.1437-0.50932 1.1437-1.1499v-2.5312h0.83191c0.67139 0 1.2139-0.54791 1.2139-1.2178v-7.4316l-10.209 6e-3 0.03086 2e-3zm7.4455-2.2611c-0.23923 0-0.43216-0.1928-0.43216-0.43214 0-0.23538 0.19294-0.43063 0.43216-0.43217 0.23923 0 0.43216 0.19688 0.43216 0.43217 0 0.23917-0.19294 0.43214-0.43216 0.43214m-4.6766 0c-0.23923 0-0.43216-0.1928-0.43216-0.43214 0-0.23684 0.19294-0.43063 0.43216-0.43063 0.23923 0 0.43216 0.19688 0.43216 0.43987 0 0.24297-0.19449 0.43757-0.43988 0.43757m4.8541-2.238 0.7941-1.4593c0.04629-0.0811 0.01079-0.17442-0.05866-0.21992-0.08027-0.0347-0.17287-0.0117-0.21916 0.0694l-0.8103 1.4662c-0.66985-0.31253-1.4323-0.48616-2.2303-0.48616-0.79795 0-1.5573 0.16596-2.2318 0.46534l-0.79795-1.4686c-0.04089-0.0755-0.13892-0.10413-0.21452-0.0618-0.07718 0.0347-0.10494 0.13884-0.06175 0.20826l0.79487 1.447c-1.5666 0.80799-2.6238 2.346-2.6238 4.1132h10.285c0-1.7672-1.0557-3.3053-2.6207-4.1132m-9.2127 4.3002c-0.63049 0-1.1421 0.51319-1.1421 1.1445v4.7785c0 0.63281 0.51242 1.1421 1.1452 1.1421 0.62817 0 1.1398-0.50932 1.1398-1.1421v-4.7769c0-0.62897-0.50933-1.1406-1.1344-1.1406" fill="#ffffff" stroke-width=".77172"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#a4c639" stroke-width=".27763"/>
<path d="m21.059 281.63c0-0.62897-0.50779-1.1406-1.1391-1.1406-0.63126 0-1.1421 0.50935-1.1421 1.1422v4.7769c0 0.62508 0.51165 1.1421 1.1445 1.1421 0.62818 0 1.1391-0.51705 1.1391-1.1421v-4.7846h-0.0079zm-12.929-0.92221 0.0032 7.4085c0 0.68298 0.54328 1.227 1.2139 1.227h0.82033v2.5312c0 0.63281 0.50933 1.1437 1.1344 1.1437 0.62509 0 1.1321-0.50932 1.1421-1.1328v-2.5312h1.538v2.5312c0 0.63511 0.50933 1.1444 1.1344 1.1444 0.63512 0 1.1437-0.50932 1.1437-1.1499v-2.5312h0.83191c0.67139 0 1.2139-0.54791 1.2139-1.2178v-7.4316l-10.209 6e-3 0.03086 2e-3zm7.4455-2.2611c-0.23923 0-0.43216-0.1928-0.43216-0.43214 0-0.23538 0.19294-0.43063 0.43216-0.43217 0.23923 0 0.43216 0.19688 0.43216 0.43217 0 0.23917-0.19294 0.43214-0.43216 0.43214m-4.6766 0c-0.23923 0-0.43216-0.1928-0.43216-0.43214 0-0.23684 0.19294-0.43063 0.43216-0.43063 0.23923 0 0.43216 0.19688 0.43216 0.43987 0 0.24297-0.19449 0.43757-0.43988 0.43757m4.8541-2.238 0.7941-1.4593c0.04629-0.0811 0.01079-0.17442-0.05866-0.21992-0.08027-0.0347-0.17287-0.0117-0.21916 0.0694l-0.8103 1.4662c-0.66985-0.31253-1.4323-0.48616-2.2303-0.48616-0.79795 0-1.5573 0.16596-2.2318 0.46534l-0.79795-1.4686c-0.04089-0.0755-0.13892-0.10413-0.21452-0.0618-0.07718 0.0347-0.10494 0.13884-0.06175 0.20826l0.79487 1.447c-1.5666 0.80799-2.6238 2.346-2.6238 4.1132h10.285c0-1.7672-1.0557-3.3053-2.6207-4.1132m-9.2127 4.3002c-0.63049 0-1.1421 0.51319-1.1421 1.1445v4.7785c0 0.63281 0.51242 1.1421 1.1452 1.1421 0.62817 0 1.1398-0.50932 1.1398-1.1421v-4.7769c0-0.62897-0.50933-1.1406-1.1344-1.1406" fill="#ffffff" stroke-width=".77172"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<rect x="-1.4211e-14" y="8.5449e-6" width="26.458" height="26.458" fill="#294172" stroke-width=".27763"/>
<path id="voice" d="m22.489 13.23c0-5.1145-4.1461-9.2611-9.2602-9.2611-5.1122 0-9.2567 4.1428-9.2602 9.2541v7.1663c0.00273 1.1606 0.94405 2.1001 2.1054 2.1001h7.1587c5.1128-0.0018 9.2567-4.1468 9.2567-9.2602" fill="#ffffff" stroke-width=".069562"/>
<path id="in" d="m9.3076 13.825h3.3282v3.3282c0 1.8372-1.491 3.3282-3.3282 3.3282s-3.3282-1.491-3.3282-3.3282 1.491-3.3282 3.3282-3.3282z" fill="none" stroke="#3c6eb4" stroke-width="2.0319"/>
<use id="finity" transform="rotate(180 12.628 13.834)" width="100%" height="100%" xlink:href="#in"/>
<path id="free" d="m13.654 12.819v4.3369c0 2.4002-1.946 4.3463-4.3463 4.3463-0.36415 0-0.62303-0.04112-0.96015-0.12923-0.49152-0.12863-0.89321-0.53163-0.89339-1.0004 0-0.5666 0.41128-0.9787 1.026-0.9787 0.2926 0 0.39878 0.05618 0.82744 0.05618 1.2654 0 2.2919-1.025 2.2941-2.2904v-1.9934c0-0.17862-0.14515-0.32334-0.32407-0.32334l-1.5071-2.72e-4c-0.56151 0-1.0152-0.44787-1.0152-1.0109-2.996e-4 -0.56656 0.45833-1.0126 1.0259-1.0126" fill="#294172" stroke-width=".069562"/>
<use id="dom" transform="rotate(180 12.628 13.834)" width="100%" height="100%" xlink:href="#free"/>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<rect x="-1.4211e-14" y="8.5449e-6" width="26.458" height="26.458" fill="#294172" stroke-width=".27763"/>
<path id="voice" d="m22.489 13.23c0-5.1145-4.1461-9.2611-9.2602-9.2611-5.1122 0-9.2567 4.1428-9.2602 9.2541v7.1663c0.00273 1.1606 0.94405 2.1001 2.1054 2.1001h7.1587c5.1128-0.0018 9.2567-4.1468 9.2567-9.2602" fill="#ffffff" stroke-width=".069562"/>
<path id="in" d="m9.3076 13.825h3.3282v3.3282c0 1.8372-1.491 3.3282-3.3282 3.3282s-3.3282-1.491-3.3282-3.3282 1.491-3.3282 3.3282-3.3282z" fill="none" stroke="#3c6eb4" stroke-width="2.0319"/>
<use id="finity" transform="rotate(180 12.628 13.834)" width="100%" height="100%" xlink:href="#in"/>
<path id="free" d="m13.654 12.819v4.3369c0 2.4002-1.946 4.3463-4.3463 4.3463-0.36415 0-0.62303-0.04112-0.96015-0.12923-0.49152-0.12863-0.89321-0.53163-0.89339-1.0004 0-0.5666 0.41128-0.9787 1.026-0.9787 0.2926 0 0.39878 0.05618 0.82744 0.05618 1.2654 0 2.2919-1.025 2.2941-2.2904v-1.9934c0-0.17862-0.14515-0.32334-0.32407-0.32334l-1.5071-2.72e-4c-0.56151 0-1.0152-0.44787-1.0152-1.0109-2.996e-4 -0.56656 0.45833-1.0126 1.0259-1.0126" fill="#294172" stroke-width=".069562"/>
<use id="dom" transform="rotate(180 12.628 13.834)" width="100%" height="100%" xlink:href="#free"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#990000" stroke-width=".27763"/>
<path d="m22.42 274.83c0.99718 0.99658-1.7672 5.3777-2.2346 5.8453-0.46729 0.46662-1.6543 0.0373-2.6509-0.95968-0.99718-0.99659-1.4267-2.1838-0.95938-2.6512 0.46707-0.46751 4.8479-3.2317 5.8449-2.2345m-13.983 1.0545c-1.5223-0.86371-3.6886-1.8246-4.3776-1.1354-0.6982 0.6979 0.29779 2.9128 1.1707 4.4379a9.3614 9.3614 0 0 1 3.2069 -3.3025" fill="#ffffff" stroke-width=".073821"/>
<path d="m20.831 280.03c0.14342 0.48638 0.11767 0.88818-0.11495 1.1204-0.54326 0.54348-2.0108-0.0351-3.3337-1.2941a6.7507 6.7507 0 0 1 -0.27393 -0.25891c-0.47838-0.47853-0.85057-0.98787-1.0886-1.457-0.46335-0.83123-0.57928-1.5654-0.22907-1.9156 0.19085-0.19062 0.4962-0.24258 0.8687-0.17559 0.24289-0.15363 0.52966-0.32476 0.84408-0.50006-1.2786-0.66689-2.7322-1.0435-4.2742-1.0435-5.1145 0-9.2608 4.1456-9.2608 9.2606 0 5.1141 4.1464 9.2602 9.2608 9.2602 5.1146 0 9.2607-4.1461 9.2607-9.2602 0-1.6518-0.43352-3.2006-1.1908-4.5433-0.16366 0.2987-0.3228 0.57233-0.46811 0.80715" fill="#ffffff" stroke-width=".075526"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#990000" stroke-width=".27763"/>
<path d="m22.42 274.83c0.99718 0.99658-1.7672 5.3777-2.2346 5.8453-0.46729 0.46662-1.6543 0.0373-2.6509-0.95968-0.99718-0.99659-1.4267-2.1838-0.95938-2.6512 0.46707-0.46751 4.8479-3.2317 5.8449-2.2345m-13.983 1.0545c-1.5223-0.86371-3.6886-1.8246-4.3776-1.1354-0.6982 0.6979 0.29779 2.9128 1.1707 4.4379a9.3614 9.3614 0 0 1 3.2069 -3.3025" fill="#ffffff" stroke-width=".073821"/>
<path d="m20.831 280.03c0.14342 0.48638 0.11767 0.88818-0.11495 1.1204-0.54326 0.54348-2.0108-0.0351-3.3337-1.2941a6.7507 6.7507 0 0 1 -0.27393 -0.25891c-0.47838-0.47853-0.85057-0.98787-1.0886-1.457-0.46335-0.83123-0.57928-1.5654-0.22907-1.9156 0.19085-0.19062 0.4962-0.24258 0.8687-0.17559 0.24289-0.15363 0.52966-0.32476 0.84408-0.50006-1.2786-0.66689-2.7322-1.0435-4.2742-1.0435-5.1145 0-9.2608 4.1456-9.2608 9.2606 0 5.1141 4.1464 9.2602 9.2608 9.2602 5.1146 0 9.2607-4.1461 9.2607-9.2602 0-1.6518-0.43352-3.2006-1.1908-4.5433-0.16366 0.2987-0.3228 0.57233-0.46811 0.80715" fill="#ffffff" stroke-width=".075526"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#73ba25" stroke-width=".27763"/>
<path d="m11.815 286.7 0.0272-3e-3 0.0049-0.0319c-0.0073-0.0247-0.02355-0.0471-0.04953-0.35762-0.02172-0.27466-0.06577-1.0274 0.32276-1.401 0.15042-0.14554 0.38102-0.27545 0.5621-0.31703 0.74439-0.17742 1.6173-0.0547 2.442 0.87606 0.4267 0.4812 0.63517 0.70041 0.73992 0.79883l0.03613 0.0321 0.04324 0.0311c0.03451 0.0186 1.4185 0.64 1.4185 0.64l0.02822-7e-3 3.91e-4 -0.0289c-0.0087-0.0101-0.87694-1.1044-0.72307-2.0056 0.1222-0.71783 0.70805-0.65327 1.5178-0.56376 0.2645 0.0295 0.56616 0.0636 0.87735 0.0701 0.87024 5e-3 1.8079-0.1507 2.386-0.39724 0.37351-0.15901 0.61183-0.26417 0.76123-0.39684 0.054-0.0434 0.08161-0.11426 0.11063-0.18971l0.0203-0.0507c0.02416-0.061 0.05948-0.1909 0.07491-0.2614 0.0071-0.0315 0.01035-0.065-0.01197-0.082l-0.08039 0.0145c-0.25293 0.14871-0.8873 0.4309-1.4809 0.44219-0.73586 0.0149-2.2179-0.722-2.3728-0.79982l-0.01462-0.0172c-0.03694-0.0863-0.25882-0.59941-0.30652-0.70793 1.0674 0.68555 1.9518 1.0646 2.6294 1.1236 0.75454 0.0653 1.342-0.33585 1.5939-0.50754 0.04913-0.0321 0.08648-0.0584 0.1015-0.0642l0.01624-0.0257c-0.04162-0.25821-0.43563-1.5089-0.73342-1.8099-0.08242-0.082-0.14859-0.16237-0.28196-0.23841-1.0781-0.61309-3.6369-0.983-3.7571-1l-0.0203 6e-3 -0.0075 0.0178s-0.01035 0.51764-0.01117 0.57506c-0.26227-0.085-2.1621-0.68358-3.943-0.74378-1.5101-0.0521-3.7091-0.24218-6.6238 1.5054l-0.08627 0.0527c-1.371 0.83467-2.3174 1.863-2.8123 3.0587-0.15509 0.37585-0.36418 1.225-0.15793 2.0234 0.08972 0.34912 0.25618 0.69941 0.48008 1.0139 0.50607 0.70932 1.3552 1.18 2.2707 1.2596 1.2913 0.11227 2.2701-0.45348 2.6176-1.5131 0.23933-0.73109 0-1.8042-0.91673-2.3515-0.74581-0.44535-1.548-0.34357-2.0131-0.044-0.40416 0.26119-0.63294 0.66654-0.62888 1.1123 0.0093 0.79011 0.70764 1.2101 1.2092 1.2111 0.14616 0 0.29231-0.0244 0.45735-0.077 0.05846-0.0176 0.11449-0.039 0.17498-0.0756l0.01908-0.0115 0.01259-8e-3 -0.0049 2e-3c0.11449-0.0754 0.18391-0.1992 0.18391-0.33207 0-0.036-0.0055-0.0731-0.01604-0.1101-0.05887-0.19961-0.26146-0.32061-0.47156-0.28377l-0.02842 6e-3 -0.03857 0.0121-0.05582 0.0182c-0.1155 0.0283-0.20218 0.0301-0.22045 0.0309-0.05927-4e-3 -0.34794-0.0881-0.34794-0.39684v-4e-3c6.12e-4 -0.11308 0.04709-0.19288 0.07288-0.23625 0.08911-0.13723 0.33535-0.27248 0.66847-0.24357 0.43583 0.0364 0.75007 0.25446 0.95814 0.66616 0.19366 0.38298 0.14311 0.85327-0.13032 1.1986-0.271 0.34218-0.75352 0.48694-1.3962 0.41902-0.64776-0.0695-1.195-0.43328-1.5018-0.99942-0.30003-0.55289-0.31667-1.2089-0.04243-1.7127 0.65588-1.207 1.8938-1.1943 2.5728-1.0806 1.0052 0.1701 2.1479 1.0749 2.5539 2.1188 0.06516 0.16634 0.09845 0.29842 0.12667 0.41823l0.04405 0.18079 1.1352 0.5408zm7.9773-5.8922c-0.21416 0.19426-0.33616 0.45902-0.34651 0.74418-0.0199 0.58813 0.45309 1.0832 1.0554 1.1054 0.29414 0.01 0.57204-0.0913 0.7858-0.28653 0.21376-0.19426 0.33576-0.45863 0.34692-0.74319 0.0203-0.58833-0.45268-1.0846-1.0566-1.106-0.29211-0.01-0.57123 0.0915-0.78498 0.28613" clip-rule="evenodd" fill="#ffffff" fill-rule="evenodd" stroke-width=".20049"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#73ba25" stroke-width=".27763"/>
<path d="m11.815 286.7 0.0272-3e-3 0.0049-0.0319c-0.0073-0.0247-0.02355-0.0471-0.04953-0.35762-0.02172-0.27466-0.06577-1.0274 0.32276-1.401 0.15042-0.14554 0.38102-0.27545 0.5621-0.31703 0.74439-0.17742 1.6173-0.0547 2.442 0.87606 0.4267 0.4812 0.63517 0.70041 0.73992 0.79883l0.03613 0.0321 0.04324 0.0311c0.03451 0.0186 1.4185 0.64 1.4185 0.64l0.02822-7e-3 3.91e-4 -0.0289c-0.0087-0.0101-0.87694-1.1044-0.72307-2.0056 0.1222-0.71783 0.70805-0.65327 1.5178-0.56376 0.2645 0.0295 0.56616 0.0636 0.87735 0.0701 0.87024 5e-3 1.8079-0.1507 2.386-0.39724 0.37351-0.15901 0.61183-0.26417 0.76123-0.39684 0.054-0.0434 0.08161-0.11426 0.11063-0.18971l0.0203-0.0507c0.02416-0.061 0.05948-0.1909 0.07491-0.2614 0.0071-0.0315 0.01035-0.065-0.01197-0.082l-0.08039 0.0145c-0.25293 0.14871-0.8873 0.4309-1.4809 0.44219-0.73586 0.0149-2.2179-0.722-2.3728-0.79982l-0.01462-0.0172c-0.03694-0.0863-0.25882-0.59941-0.30652-0.70793 1.0674 0.68555 1.9518 1.0646 2.6294 1.1236 0.75454 0.0653 1.342-0.33585 1.5939-0.50754 0.04913-0.0321 0.08648-0.0584 0.1015-0.0642l0.01624-0.0257c-0.04162-0.25821-0.43563-1.5089-0.73342-1.8099-0.08242-0.082-0.14859-0.16237-0.28196-0.23841-1.0781-0.61309-3.6369-0.983-3.7571-1l-0.0203 6e-3 -0.0075 0.0178s-0.01035 0.51764-0.01117 0.57506c-0.26227-0.085-2.1621-0.68358-3.943-0.74378-1.5101-0.0521-3.7091-0.24218-6.6238 1.5054l-0.08627 0.0527c-1.371 0.83467-2.3174 1.863-2.8123 3.0587-0.15509 0.37585-0.36418 1.225-0.15793 2.0234 0.08972 0.34912 0.25618 0.69941 0.48008 1.0139 0.50607 0.70932 1.3552 1.18 2.2707 1.2596 1.2913 0.11227 2.2701-0.45348 2.6176-1.5131 0.23933-0.73109 0-1.8042-0.91673-2.3515-0.74581-0.44535-1.548-0.34357-2.0131-0.044-0.40416 0.26119-0.63294 0.66654-0.62888 1.1123 0.0093 0.79011 0.70764 1.2101 1.2092 1.2111 0.14616 0 0.29231-0.0244 0.45735-0.077 0.05846-0.0176 0.11449-0.039 0.17498-0.0756l0.01908-0.0115 0.01259-8e-3 -0.0049 2e-3c0.11449-0.0754 0.18391-0.1992 0.18391-0.33207 0-0.036-0.0055-0.0731-0.01604-0.1101-0.05887-0.19961-0.26146-0.32061-0.47156-0.28377l-0.02842 6e-3 -0.03857 0.0121-0.05582 0.0182c-0.1155 0.0283-0.20218 0.0301-0.22045 0.0309-0.05927-4e-3 -0.34794-0.0881-0.34794-0.39684v-4e-3c6.12e-4 -0.11308 0.04709-0.19288 0.07288-0.23625 0.08911-0.13723 0.33535-0.27248 0.66847-0.24357 0.43583 0.0364 0.75007 0.25446 0.95814 0.66616 0.19366 0.38298 0.14311 0.85327-0.13032 1.1986-0.271 0.34218-0.75352 0.48694-1.3962 0.41902-0.64776-0.0695-1.195-0.43328-1.5018-0.99942-0.30003-0.55289-0.31667-1.2089-0.04243-1.7127 0.65588-1.207 1.8938-1.1943 2.5728-1.0806 1.0052 0.1701 2.1479 1.0749 2.5539 2.1188 0.06516 0.16634 0.09845 0.29842 0.12667 0.41823l0.04405 0.18079 1.1352 0.5408zm7.9773-5.8922c-0.21416 0.19426-0.33616 0.45902-0.34651 0.74418-0.0199 0.58813 0.45309 1.0832 1.0554 1.1054 0.29414 0.01 0.57204-0.0913 0.7858-0.28653 0.21376-0.19426 0.33576-0.45863 0.34692-0.74319 0.0203-0.58833-0.45268-1.0846-1.0566-1.106-0.29211-0.01-0.57123 0.0915-0.78498 0.28613" clip-rule="evenodd" fill="#ffffff" fill-rule="evenodd" stroke-width=".20049"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<rect x="-1.4211e-14" y="8.5449e-6" width="26.458" height="26.458" fill="#dd4814" stroke-width=".27763"/>
<circle cx="13.229" cy="13.229" r="9.2604" fill="#ffffff" stroke-width=".065339"/>
<g transform="matrix(.87503 0 0 .87503 1.6534 -235.08)" fill="#dd4814" stroke-width=".074671">
<circle cx="6.0325" cy="283.77" r="1.4129"/>
<path d="m9.8237 288.88c-1.2365-0.82612-2.1564-2.0891-2.5385-3.5684 0.44639-0.36374 0.73151-0.91772 0.73151-1.5387s-0.28512-1.175-0.73151-1.5387c0.38207-1.4793 1.3019-2.7423 2.5385-3.5684l1.033 1.7304c-1.0611 0.74683-1.7551 1.9802-1.7551 3.3767 0 1.3966 0.69392 2.6299 1.7551 3.3767z"/>
<circle transform="rotate(120)" cx="231.94" cy="-153.34" r="1.4129"/>
<path d="m10.509 278.27c1.3337-0.6578 2.8874-0.82293 4.3596-0.41416 0.0918 0.56846 0.42901 1.0924 0.96681 1.4029s1.1601 0.34057 1.6983 0.13585c1.0901 1.0705 1.7239 2.4987 1.8211 3.9826l-2.0151 0.0294c-0.1162-1.2924-0.83735-2.51-2.0468-3.2083-1.2094-0.69828-2.6245-0.714-3.8019-0.16843z"/>
<circle transform="rotate(240)" cx="-259.56" cy="-130.43" r="1.4129"/>
<path d="m19.355 284.17c-0.09718 1.4839-0.73103 2.912-1.8211 3.9826-0.5382-0.20472-1.1605-0.17465-1.6983 0.13585s-0.87501 0.83441-0.96681 1.4029c-1.4722 0.40877-3.0259 0.24364-4.3596-0.41416l0.98207-1.7598c1.1773 0.54557 2.5924 0.52985 3.8019-0.16843 1.2094-0.69827 1.9306-1.9159 2.0468-3.2083z"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<rect x="-1.4211e-14" y="8.5449e-6" width="26.458" height="26.458" fill="#dd4814" stroke-width=".27763"/>
<circle cx="13.229" cy="13.229" r="9.2604" fill="#ffffff" stroke-width=".065339"/>
<g transform="matrix(.87503 0 0 .87503 1.6534 -235.08)" fill="#dd4814" stroke-width=".074671">
<circle cx="6.0325" cy="283.77" r="1.4129"/>
<path d="m9.8237 288.88c-1.2365-0.82612-2.1564-2.0891-2.5385-3.5684 0.44639-0.36374 0.73151-0.91772 0.73151-1.5387s-0.28512-1.175-0.73151-1.5387c0.38207-1.4793 1.3019-2.7423 2.5385-3.5684l1.033 1.7304c-1.0611 0.74683-1.7551 1.9802-1.7551 3.3767 0 1.3966 0.69392 2.6299 1.7551 3.3767z"/>
<circle transform="rotate(120)" cx="231.94" cy="-153.34" r="1.4129"/>
<path d="m10.509 278.27c1.3337-0.6578 2.8874-0.82293 4.3596-0.41416 0.0918 0.56846 0.42901 1.0924 0.96681 1.4029s1.1601 0.34057 1.6983 0.13585c1.0901 1.0705 1.7239 2.4987 1.8211 3.9826l-2.0151 0.0294c-0.1162-1.2924-0.83735-2.51-2.0468-3.2083-1.2094-0.69828-2.6245-0.714-3.8019-0.16843z"/>
<circle transform="rotate(240)" cx="-259.56" cy="-130.43" r="1.4129"/>
<path d="m19.355 284.17c-0.09718 1.4839-0.73103 2.912-1.8211 3.9826-0.5382-0.20472-1.1605-0.17465-1.6983 0.13585s-0.87501 0.83441-0.96681 1.4029c-1.4722 0.40877-3.0259 0.24364-4.3596-0.41416l0.98207-1.7598c1.1773 0.54557 2.5924 0.52985 3.8019-0.16843 1.2094-0.69827 1.9306-1.9159 2.0468-3.2083z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#0078d7" stroke-width=".27763"/>
<path d="m3.9688 277.17 7.5241-1.041v7.2933h-7.5241m8.4494-7.4099 10.071-1.504v8.7974h-10.071m-8.4494 0.92604h7.5241v7.2934l-7.5241-1.0434m8.4494-6.25h10.071v8.7974l-9.9549-1.3898" fill="#ffffff" stroke-width=".7717"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="100" height="100" version="1.1" viewBox="0 0 26.458333 26.458334" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="translate(0 -270.54)">
<rect x="-1.4211e-14" y="270.54" width="26.458" height="26.458" fill="#0078d7" stroke-width=".27763"/>
<path d="m3.9688 277.17 7.5241-1.041v7.2933h-7.5241m8.4494-7.4099 10.071-1.504v8.7974h-10.071m-8.4494 0.92604h7.5241v7.2934l-7.5241-1.0434m8.4494-6.25h10.071v8.7974l-9.9549-1.3898" fill="#ffffff" stroke-width=".7717"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 963 B

After

Width:  |  Height:  |  Size: 946 B

View File

@ -1,182 +1,182 @@
diff --git a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
index 638446d776..063be46a7d 100644
--- a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
+++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
@@ -564,8 +564,10 @@ static int
socketpair(int, int, int, SOCKET sockets[2]) // we ignore the first two params: we only use this for a strictly limited case
{
int result = 0;
+ socklen_t name_length = 0;
+ int reuse = 1;
- // initialize with default values
+ // initialize with default values
sockets[0] = INVALID_SOCKET;
sockets[1] = INVALID_SOCKET;
@@ -578,15 +580,14 @@ socketpair(int, int, int, SOCKET sockets[2]) // we ignore the first two params:
memset(&inet_address, 0, sizeof(inet_address));
inet_address.sin_family = AF_INET;
inet_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- int reuse = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
result = bind(listener, (const sockaddr*)&inet_address, sizeof(inet_address));
if (result != 0) goto fail;
listen(listener, 1);
// read the port that was assigned to the listener socket
- socklen_t name_length = sizeof(inet_address);
- result = getsockname(listener, (struct sockaddr*)&inet_address, &name_length);
+ name_length = sizeof(inet_address);
+ result = getsockname(listener, (struct sockaddr*)&inet_address, &name_length);
if (result != 0) goto fail;
// create the first socket
diff --git a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
index 8f3c6b7a0d..3ab979ad3b 100644
--- a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
+++ b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
@@ -441,7 +441,7 @@ NPT_Win32Thread::NPT_Win32Thread(NPT_Thread* delegator,
m_Delegator(delegator),
m_Target(target),
m_Detached(detached),
- m_ThreadHandle(0),
+ m_ThreadHandle(nullptr),
m_ThreadId(0)
{
}
@@ -567,7 +567,7 @@ NPT_Win32Thread::EntryPoint(void* argument)
NPT_Result
NPT_Win32Thread::Start()
{
- if (m_ThreadHandle > 0) {
+ if (m_ThreadHandle != nullptr) {
// failed
NPT_LOG_WARNING("thread already started !");
return NPT_ERROR_INVALID_STATE;
diff --git a/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp b/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
index bae654572c..7d476d1806 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
+++ b/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
@@ -805,8 +805,9 @@ PLT_CtrlPoint::ProcessEventNotification(PLT_EventSubscriberReference subscriber,
var = service->FindStateVariable(property->GetTag());
if (var == NULL) continue;
- if (NPT_FAILED(var->SetValue(property->GetText()?*property->GetText():""))) {
- NPT_CHECK_LABEL_WARNING(NPT_FAILURE, failure);
+ if (NPT_FAILED(var->SetValue(property->GetText() ? property->GetText()->GetChars() : "")))
+ {
+ NPT_CHECK_LABEL_WARNING(NPT_FAILURE, failure);
}
vars.Add(var);
@@ -1662,12 +1663,11 @@ PLT_CtrlPoint::ProcessSubscribeResponse(NPT_Result res,
goto remove_sub;
failure:
- NPT_LOG_SEVERE_4("%subscription failed of sub \"%s\" for service \"%s\" of device \"%s\"",
- (const char*)subscription?"S":"Uns",
- (const char*)(sid?*sid:"Unknown"),
- (const char*)service->GetServiceID(),
- (const char*)service->GetDevice()->GetFriendlyName());
- res = NPT_FAILED(res)?res:NPT_FAILURE;
+ NPT_LOG_SEVERE_4(
+ "%subscription failed of sub \"%s\" for service \"%s\" of device \"%s\"",
+ (const char*)subscription ? "S" : "Uns", (const char*)(sid ? sid->GetChars() : "Unknown"),
+ (const char*)service->GetServiceID(), (const char*)service->GetDevice()->GetFriendlyName());
+ res = NPT_FAILED(res) ? res : NPT_FAILURE;
remove_sub:
// in case it was a renewal look for the subscriber with that service and remove it from the list
@@ -1814,7 +1814,8 @@ PLT_CtrlPoint::ProcessActionResponse(NPT_Result res,
NPT_XmlElementNode* child = (*args)->AsElementNode();
if (!child) continue;
- action->SetArgumentValue(child->GetTag(), child->GetText()?*child->GetText():"");
+ action->SetArgumentValue(child->GetTag(),
+ child->GetText() ? child->GetText()->GetChars() : "");
if (NPT_FAILED(res)) goto failure;
}
diff --git a/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp b/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
index b6de5c202d..6f5f09f9cf 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
+++ b/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
@@ -305,11 +305,12 @@ PLT_DeviceHost::Announce(PLT_DeviceData* device,
break;
}
PLT_UPnPMessageHelper::SetNTS(req, nts);
-
- NPT_LOG_FINER_3("Sending SSDP NOTIFY (%s) Request to %s (%s)",
- nts.GetChars(),
+
+ NPT_LOG_FINER_3("Sending SSDP NOTIFY (%s) Request to %s (%s)", nts.GetChars(),
(const char*)req.GetUrl().ToString(),
- (const char*)(PLT_UPnPMessageHelper::GetLocation(req)?*PLT_UPnPMessageHelper::GetLocation(req):""));
+ (const char*)(PLT_UPnPMessageHelper::GetLocation(req)
+ ? PLT_UPnPMessageHelper::GetLocation(req)->GetChars()
+ : ""));
// upnp:rootdevice
if (device->m_ParentUUID.IsEmpty()) {
@@ -585,14 +586,13 @@ PLT_DeviceHost::ProcessHttpPostRequest(NPT_HttpRequest& request,
name = "ObjectID";
}
- res = action->SetArgumentValue(
- name,
- child->GetText()?*child->GetText():"");
+ res = action->SetArgumentValue(name, child->GetText() ? child->GetText()->GetChars() : "");
- // test if value was correct
- if (res == NPT_ERROR_INVALID_PARAMETERS) {
- action->SetError(701, "Invalid Name");
- goto error;
+ // test if value was correct
+ if (res == NPT_ERROR_INVALID_PARAMETERS)
+ {
+ action->SetError(701, "Invalid Name");
+ goto error;
}
}
diff --git a/lib/libUPnP/Platinum/Source/Core/PltUtilities.h b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
index bdc1340173..4677f5be0e 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
+++ b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
@@ -140,7 +140,8 @@ public:
const NPT_String* text = child->GetText();
// DLNA 7.3.17
- value = text?text->SubString(0, max_size):"";
+ if (text)
+ value = text->SubString(0, max_size);
return NPT_SUCCESS;
}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
index feeb537648..8686aa9294 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
@@ -401,7 +401,7 @@ PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_
NPT_XmlElementNode* child = (*children)->AsElementNode();
if (!child) continue;
const NPT_String *txt = child->GetText();
- tags[child->GetTag()] = txt ? *txt : "";
+ tags[child->GetTag()] = txt ? txt->GetChars() : "";
}
return NPT_SUCCESS;
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
index 27d81fae86..794b56be17 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
@@ -245,7 +245,7 @@ PLT_SyncMediaBrowser::OnMSStateVariablesChanged(PLT_Service* se
if (value.GetLength()) {
index = value.Find(',');
update_id = (index<0)?value:value.Left(index);
- value = (index<0)?"":value.SubString(index+1);
+ value = (index < 0) ? "" : value.SubString(index + 1).GetChars();
// clear cache for that device
if (m_UseCache) m_Cache.Clear(device->GetUUID(), item_id);
diff --git a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
index 638446d776..063be46a7d 100644
--- a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
+++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdSockets.cpp
@@ -564,8 +564,10 @@ static int
socketpair(int, int, int, SOCKET sockets[2]) // we ignore the first two params: we only use this for a strictly limited case
{
int result = 0;
+ socklen_t name_length = 0;
+ int reuse = 1;
- // initialize with default values
+ // initialize with default values
sockets[0] = INVALID_SOCKET;
sockets[1] = INVALID_SOCKET;
@@ -578,15 +580,14 @@ socketpair(int, int, int, SOCKET sockets[2]) // we ignore the first two params:
memset(&inet_address, 0, sizeof(inet_address));
inet_address.sin_family = AF_INET;
inet_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- int reuse = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
result = bind(listener, (const sockaddr*)&inet_address, sizeof(inet_address));
if (result != 0) goto fail;
listen(listener, 1);
// read the port that was assigned to the listener socket
- socklen_t name_length = sizeof(inet_address);
- result = getsockname(listener, (struct sockaddr*)&inet_address, &name_length);
+ name_length = sizeof(inet_address);
+ result = getsockname(listener, (struct sockaddr*)&inet_address, &name_length);
if (result != 0) goto fail;
// create the first socket
diff --git a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
index 8f3c6b7a0d..3ab979ad3b 100644
--- a/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
+++ b/lib/libUPnP/Neptune/Source/System/Win32/NptWin32Threads.cpp
@@ -441,7 +441,7 @@ NPT_Win32Thread::NPT_Win32Thread(NPT_Thread* delegator,
m_Delegator(delegator),
m_Target(target),
m_Detached(detached),
- m_ThreadHandle(0),
+ m_ThreadHandle(nullptr),
m_ThreadId(0)
{
}
@@ -567,7 +567,7 @@ NPT_Win32Thread::EntryPoint(void* argument)
NPT_Result
NPT_Win32Thread::Start()
{
- if (m_ThreadHandle > 0) {
+ if (m_ThreadHandle != nullptr) {
// failed
NPT_LOG_WARNING("thread already started !");
return NPT_ERROR_INVALID_STATE;
diff --git a/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp b/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
index bae654572c..7d476d1806 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
+++ b/lib/libUPnP/Platinum/Source/Core/PltCtrlPoint.cpp
@@ -805,8 +805,9 @@ PLT_CtrlPoint::ProcessEventNotification(PLT_EventSubscriberReference subscriber,
var = service->FindStateVariable(property->GetTag());
if (var == NULL) continue;
- if (NPT_FAILED(var->SetValue(property->GetText()?*property->GetText():""))) {
- NPT_CHECK_LABEL_WARNING(NPT_FAILURE, failure);
+ if (NPT_FAILED(var->SetValue(property->GetText() ? property->GetText()->GetChars() : "")))
+ {
+ NPT_CHECK_LABEL_WARNING(NPT_FAILURE, failure);
}
vars.Add(var);
@@ -1662,12 +1663,11 @@ PLT_CtrlPoint::ProcessSubscribeResponse(NPT_Result res,
goto remove_sub;
failure:
- NPT_LOG_SEVERE_4("%subscription failed of sub \"%s\" for service \"%s\" of device \"%s\"",
- (const char*)subscription?"S":"Uns",
- (const char*)(sid?*sid:"Unknown"),
- (const char*)service->GetServiceID(),
- (const char*)service->GetDevice()->GetFriendlyName());
- res = NPT_FAILED(res)?res:NPT_FAILURE;
+ NPT_LOG_SEVERE_4(
+ "%subscription failed of sub \"%s\" for service \"%s\" of device \"%s\"",
+ (const char*)subscription ? "S" : "Uns", (const char*)(sid ? sid->GetChars() : "Unknown"),
+ (const char*)service->GetServiceID(), (const char*)service->GetDevice()->GetFriendlyName());
+ res = NPT_FAILED(res) ? res : NPT_FAILURE;
remove_sub:
// in case it was a renewal look for the subscriber with that service and remove it from the list
@@ -1814,7 +1814,8 @@ PLT_CtrlPoint::ProcessActionResponse(NPT_Result res,
NPT_XmlElementNode* child = (*args)->AsElementNode();
if (!child) continue;
- action->SetArgumentValue(child->GetTag(), child->GetText()?*child->GetText():"");
+ action->SetArgumentValue(child->GetTag(),
+ child->GetText() ? child->GetText()->GetChars() : "");
if (NPT_FAILED(res)) goto failure;
}
diff --git a/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp b/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
index b6de5c202d..6f5f09f9cf 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
+++ b/lib/libUPnP/Platinum/Source/Core/PltDeviceHost.cpp
@@ -305,11 +305,12 @@ PLT_DeviceHost::Announce(PLT_DeviceData* device,
break;
}
PLT_UPnPMessageHelper::SetNTS(req, nts);
-
- NPT_LOG_FINER_3("Sending SSDP NOTIFY (%s) Request to %s (%s)",
- nts.GetChars(),
+
+ NPT_LOG_FINER_3("Sending SSDP NOTIFY (%s) Request to %s (%s)", nts.GetChars(),
(const char*)req.GetUrl().ToString(),
- (const char*)(PLT_UPnPMessageHelper::GetLocation(req)?*PLT_UPnPMessageHelper::GetLocation(req):""));
+ (const char*)(PLT_UPnPMessageHelper::GetLocation(req)
+ ? PLT_UPnPMessageHelper::GetLocation(req)->GetChars()
+ : ""));
// upnp:rootdevice
if (device->m_ParentUUID.IsEmpty()) {
@@ -585,14 +586,13 @@ PLT_DeviceHost::ProcessHttpPostRequest(NPT_HttpRequest& request,
name = "ObjectID";
}
- res = action->SetArgumentValue(
- name,
- child->GetText()?*child->GetText():"");
+ res = action->SetArgumentValue(name, child->GetText() ? child->GetText()->GetChars() : "");
- // test if value was correct
- if (res == NPT_ERROR_INVALID_PARAMETERS) {
- action->SetError(701, "Invalid Name");
- goto error;
+ // test if value was correct
+ if (res == NPT_ERROR_INVALID_PARAMETERS)
+ {
+ action->SetError(701, "Invalid Name");
+ goto error;
}
}
diff --git a/lib/libUPnP/Platinum/Source/Core/PltUtilities.h b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
index bdc1340173..4677f5be0e 100644
--- a/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
+++ b/lib/libUPnP/Platinum/Source/Core/PltUtilities.h
@@ -140,7 +140,8 @@ public:
const NPT_String* text = child->GetText();
// DLNA 7.3.17
- value = text?text->SubString(0, max_size):"";
+ if (text)
+ value = text->SubString(0, max_size);
return NPT_SUCCESS;
}
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
index feeb537648..8686aa9294 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltMediaServer.cpp
@@ -401,7 +401,7 @@ PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_
NPT_XmlElementNode* child = (*children)->AsElementNode();
if (!child) continue;
const NPT_String *txt = child->GetText();
- tags[child->GetTag()] = txt ? *txt : "";
+ tags[child->GetTag()] = txt ? txt->GetChars() : "";
}
return NPT_SUCCESS;
diff --git a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
index 27d81fae86..794b56be17 100644
--- a/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
+++ b/lib/libUPnP/Platinum/Source/Devices/MediaServer/PltSyncMediaBrowser.cpp
@@ -245,7 +245,7 @@ PLT_SyncMediaBrowser::OnMSStateVariablesChanged(PLT_Service* se
if (value.GetLength()) {
index = value.Find(',');
update_id = (index<0)?value:value.Left(index);
- value = (index<0)?"":value.SubString(index+1);
+ value = (index < 0) ? "" : value.SubString(index + 1).GetChars();
// clear cache for that device
if (m_UseCache) m_Cache.Clear(device->GetUUID(), item_id);

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Kodi_Icon" xmlns:xodm="http://www.corel.com/coreldraw/odm/2003"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256"
style="enable-background:new 0 0 256 256;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Border_00000101104235666603682920000002035333013992593321_);}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Kodi_00000034792859328757966830000000135640982814228155_);}
</style>
<rect id="Boundary_Box" class="st0" width="256" height="256"/>
<linearGradient id="Border_00000015318469695191313500000001378236376235353531_" gradientUnits="userSpaceOnUse" x1="-351.5" y1="457.5287" x2="-351.5" y2="341.4705" gradientTransform="matrix(2 0 0 -2 831 927)">
<stop offset="0" style="stop-color:#FEFEFE"/>
<stop offset="1" style="stop-color:#DFDFDF"/>
</linearGradient>
<path id="Border" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#Border_00000015318469695191313500000001378236376235353531_);" d="
M17.3,114.9l97.6-97.6c7.2-7.2,19-7.2,26.2,0l97.6,97.6c7.2,7.2,7.2,19,0,26.2l-97.6,97.6c-7.2,7.2-19,7.2-26.2,0l-97.6-97.6
C10.1,133.9,10.1,122.1,17.3,114.9z"/>
<linearGradient id="Kodi_00000070798206131893957420000016692771746482146463_" gradientUnits="userSpaceOnUse" x1="-351.4952" y1="450.368" x2="-351.4952" y2="348.632" gradientTransform="matrix(2 0 0 -2 831 927)">
<stop offset="0" style="stop-color:#33ADDD"/>
<stop offset="1" style="stop-color:#148FBF"/>
</linearGradient>
<path id="Kodi" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#Kodi_00000070798206131893957420000016692771746482146463_);" d="
M61.6,96.1c0-4.4-2.1-6.4-4-4.4l-31.3,31.3c-2.8,2.8-2.8,7.3,0,10.1l31.3,31.3c1.9,1.9,4,0,4-4.4L61.6,96.1z M152.5,123l33.6-33.6
c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1l-33.6,33.6c-2.8,2.8-7.3,2.8-10.1,0L152.5,133
C149.7,130.3,149.7,125.7,152.5,123z M89.4,186.1l33.6-33.6c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1L133,229.7
c-2.8,2.8-7.3,2.8-10.1,0l-33.6-33.6C86.6,193.4,86.6,188.8,89.4,186.1z M88.5,65.8c0-3.5,1-6,3.4-8.5c10.4-10.4,20.7-20.7,31-31.1
c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1c-24.8,24.8-49.5,49.5-74.3,74.3c-1.9,1.9-3.8,0-3.8-4.4L88.5,65.8
L88.5,65.8z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Kodi_Icon" xmlns:xodm="http://www.corel.com/coreldraw/odm/2003"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256"
style="enable-background:new 0 0 256 256;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Border_00000101104235666603682920000002035333013992593321_);}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:url(#Kodi_00000034792859328757966830000000135640982814228155_);}
</style>
<rect id="Boundary_Box" class="st0" width="256" height="256"/>
<linearGradient id="Border_00000015318469695191313500000001378236376235353531_" gradientUnits="userSpaceOnUse" x1="-351.5" y1="457.5287" x2="-351.5" y2="341.4705" gradientTransform="matrix(2 0 0 -2 831 927)">
<stop offset="0" style="stop-color:#FEFEFE"/>
<stop offset="1" style="stop-color:#DFDFDF"/>
</linearGradient>
<path id="Border" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#Border_00000015318469695191313500000001378236376235353531_);" d="
M17.3,114.9l97.6-97.6c7.2-7.2,19-7.2,26.2,0l97.6,97.6c7.2,7.2,7.2,19,0,26.2l-97.6,97.6c-7.2,7.2-19,7.2-26.2,0l-97.6-97.6
C10.1,133.9,10.1,122.1,17.3,114.9z"/>
<linearGradient id="Kodi_00000070798206131893957420000016692771746482146463_" gradientUnits="userSpaceOnUse" x1="-351.4952" y1="450.368" x2="-351.4952" y2="348.632" gradientTransform="matrix(2 0 0 -2 831 927)">
<stop offset="0" style="stop-color:#33ADDD"/>
<stop offset="1" style="stop-color:#148FBF"/>
</linearGradient>
<path id="Kodi" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#Kodi_00000070798206131893957420000016692771746482146463_);" d="
M61.6,96.1c0-4.4-2.1-6.4-4-4.4l-31.3,31.3c-2.8,2.8-2.8,7.3,0,10.1l31.3,31.3c1.9,1.9,4,0,4-4.4L61.6,96.1z M152.5,123l33.6-33.6
c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1l-33.6,33.6c-2.8,2.8-7.3,2.8-10.1,0L152.5,133
C149.7,130.3,149.7,125.7,152.5,123z M89.4,186.1l33.6-33.6c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1L133,229.7
c-2.8,2.8-7.3,2.8-10.1,0l-33.6-33.6C86.6,193.4,86.6,188.8,89.4,186.1z M88.5,65.8c0-3.5,1-6,3.4-8.5c10.4-10.4,20.7-20.7,31-31.1
c2.8-2.8,7.3-2.8,10.1,0l33.6,33.6c2.8,2.8,2.8,7.3,0,10.1c-24.8,24.8-49.5,49.5-74.3,74.3c-1.9,1.9-3.8,0-3.8-4.4L88.5,65.8
L88.5,65.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,100 +1,100 @@
/*
* Copyright (C) 2023 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "OSScreenSaverWebOS.h"
#include "CompileInfo.h"
#include "utils/JSONVariantParser.h"
#include "utils/JSONVariantWriter.h"
#include "utils/log.h"
namespace
{
constexpr const char* LUNA_REGISTER_SCREENSAVER =
"luna://com.webos.service.tvpower/power/registerScreenSaverRequest";
constexpr const char* LUNA_RESPONSE_SCREENSAVER =
"luna://com.webos.service.tvpower/power/responseScreenSaverRequest";
} // namespace
namespace KODI::WINDOWING::WAYLAND
{
COSScreenSaverWebOS::~COSScreenSaverWebOS()
{
if (m_requestContext)
{
// Luna helper functions return 0 on success
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
void COSScreenSaverWebOS::Inhibit()
{
CVariant request;
request["subscribe"] = true;
request["clientName"] = CCompileInfo::GetPackage();
std::string payload;
CJSONVariantWriter::Write(request, payload, true);
m_requestContext = std::make_unique<HContext>();
m_requestContext->pub = true;
m_requestContext->multiple = true;
m_requestContext->callback = &OnScreenSaverAboutToStart;
if (HLunaServiceCall(LUNA_REGISTER_SCREENSAVER, payload.c_str(), m_requestContext.get()))
{
CLog::LogF(LOGWARNING, "Luna request call failed");
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
void COSScreenSaverWebOS::Uninhibit()
{
if (m_requestContext)
{
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
bool COSScreenSaverWebOS::OnScreenSaverAboutToStart(LSHandle* sh, LSMessage* reply, void* ctx)
{
CVariant request;
const char* msg = HLunaServiceMessage(reply);
CJSONVariantParser::Parse(msg, request);
CLog::LogF(LOGDEBUG, "Responded {}", msg);
if (request["state"] != "Active")
return true;
CVariant response;
response["clientName"] = CCompileInfo::GetPackage();
response["ack"] = false;
response["timestamp"] = request["timestamp"];
std::string payload;
CJSONVariantWriter::Write(response, payload, true);
HContext response_ctx;
response_ctx.multiple = false;
response_ctx.pub = true;
response_ctx.callback = nullptr;
if (HLunaServiceCall(LUNA_RESPONSE_SCREENSAVER, payload.c_str(), &response_ctx))
{
CLog::LogF(LOGWARNING, "Luna response call failed");
return false;
}
return true;
}
} // namespace KODI::WINDOWING::WAYLAND
/*
* Copyright (C) 2023 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#include "OSScreenSaverWebOS.h"
#include "CompileInfo.h"
#include "utils/JSONVariantParser.h"
#include "utils/JSONVariantWriter.h"
#include "utils/log.h"
namespace
{
constexpr const char* LUNA_REGISTER_SCREENSAVER =
"luna://com.webos.service.tvpower/power/registerScreenSaverRequest";
constexpr const char* LUNA_RESPONSE_SCREENSAVER =
"luna://com.webos.service.tvpower/power/responseScreenSaverRequest";
} // namespace
namespace KODI::WINDOWING::WAYLAND
{
COSScreenSaverWebOS::~COSScreenSaverWebOS()
{
if (m_requestContext)
{
// Luna helper functions return 0 on success
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
void COSScreenSaverWebOS::Inhibit()
{
CVariant request;
request["subscribe"] = true;
request["clientName"] = CCompileInfo::GetPackage();
std::string payload;
CJSONVariantWriter::Write(request, payload, true);
m_requestContext = std::make_unique<HContext>();
m_requestContext->pub = true;
m_requestContext->multiple = true;
m_requestContext->callback = &OnScreenSaverAboutToStart;
if (HLunaServiceCall(LUNA_REGISTER_SCREENSAVER, payload.c_str(), m_requestContext.get()))
{
CLog::LogF(LOGWARNING, "Luna request call failed");
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
void COSScreenSaverWebOS::Uninhibit()
{
if (m_requestContext)
{
if (HUnregisterServiceCallback(m_requestContext.get()))
CLog::LogF(LOGWARNING, "Luna request unregister failed");
m_requestContext = nullptr;
}
}
bool COSScreenSaverWebOS::OnScreenSaverAboutToStart(LSHandle* sh, LSMessage* reply, void* ctx)
{
CVariant request;
const char* msg = HLunaServiceMessage(reply);
CJSONVariantParser::Parse(msg, request);
CLog::LogF(LOGDEBUG, "Responded {}", msg);
if (request["state"] != "Active")
return true;
CVariant response;
response["clientName"] = CCompileInfo::GetPackage();
response["ack"] = false;
response["timestamp"] = request["timestamp"];
std::string payload;
CJSONVariantWriter::Write(response, payload, true);
HContext response_ctx;
response_ctx.multiple = false;
response_ctx.pub = true;
response_ctx.callback = nullptr;
if (HLunaServiceCall(LUNA_RESPONSE_SCREENSAVER, payload.c_str(), &response_ctx))
{
CLog::LogF(LOGWARNING, "Luna response call failed");
return false;
}
return true;
}
} // namespace KODI::WINDOWING::WAYLAND

View File

@ -1,38 +1,38 @@
/*
* Copyright (C) 2023 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include "xbmc/windowing/OSScreenSaver.h"
#include <webos-helpers/libhelpers.h>
namespace KODI::WINDOWING::WAYLAND
{
class COSScreenSaverWebOS : public IOSScreenSaver
{
public:
~COSScreenSaverWebOS() override;
/**
* Screensaver inhibition on webOS works by subscribing to the tvpower service. The service will
* respond every few minutes with a timestamp that needs to be confirmed if the screensaver
* should still be inhibited. If those responses are not answered the screensaver will be
* uninhibited again
*/
void Inhibit() override;
void Uninhibit() override;
private:
static bool OnScreenSaverAboutToStart(LSHandle* sh, LSMessage* reply, void* ctx);
std::unique_ptr<HContext> m_requestContext;
};
} // namespace KODI::WINDOWING::WAYLAND
/*
* Copyright (C) 2023 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
#pragma once
#include "xbmc/windowing/OSScreenSaver.h"
#include <webos-helpers/libhelpers.h>
namespace KODI::WINDOWING::WAYLAND
{
class COSScreenSaverWebOS : public IOSScreenSaver
{
public:
~COSScreenSaverWebOS() override;
/**
* Screensaver inhibition on webOS works by subscribing to the tvpower service. The service will
* respond every few minutes with a timestamp that needs to be confirmed if the screensaver
* should still be inhibited. If those responses are not answered the screensaver will be
* uninhibited again
*/
void Inhibit() override;
void Uninhibit() override;
private:
static bool OnScreenSaverAboutToStart(LSHandle* sh, LSMessage* reply, void* ctx);
std::unique_ptr<HContext> m_requestContext;
};
} // namespace KODI::WINDOWING::WAYLAND