mirror of
https://github.com/jongracecox/anybadge.git
synced 2026-01-04 19:32:11 +01:00
Add style support and add GitLab Scoped labels (#50)
- Add new `--style` argument - Add new **GitLab Scoped** label style - Update documentation to reflect new argument
This commit is contained in:
314
README.md
314
README.md
@@ -178,9 +178,9 @@ badges based on version numbering. Here are some examples:
|
||||
|
||||
```python
|
||||
badge = Badge(
|
||||
label='Version',
|
||||
value='3.0.0',
|
||||
thresholds={'3.0.0': 'red', '3.2.0': 'orange', '999.0.0': 'green'},
|
||||
label='Version',
|
||||
value='3.0.0',
|
||||
thresholds={'3.0.0': 'red', '3.2.0': 'orange', '999.0.0': 'green'},
|
||||
semver=True
|
||||
)
|
||||
```
|
||||
@@ -192,7 +192,7 @@ In the above example the thresholds equate to the following:
|
||||
* If value is < 999.0.0 then badge will be green.
|
||||
|
||||
Each threshold entry is used to define the upper bounds of the threshold. If you don't know the
|
||||
upper bound for your version number threshold you will need to provide an extreme upper bound -
|
||||
upper bound for your version number threshold you will need to provide an extreme upper bound -
|
||||
in this example it is `999.0.0`.
|
||||
|
||||
### Examples
|
||||
@@ -201,37 +201,66 @@ in this example it is `999.0.0`.
|
||||
```bash
|
||||
anybadge --value=2.22 --file=pylint.svg pylint
|
||||
```
|
||||

|
||||

|
||||
|
||||
#### Pylint using arguments
|
||||
```bash
|
||||
anybadge -l pylint -v 2.22 -f pylint.svg 2=red 4=orange 8=yellow 10=green
|
||||
```
|
||||

|
||||

|
||||
|
||||
#### Coverage using template
|
||||
```bash
|
||||
anybadge --value=65 --file=coverage.svg coverage
|
||||
```
|
||||

|
||||
```
|
||||

|
||||
|
||||
#### Pipeline, using labeled colors
|
||||
```bash
|
||||
anybadge --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
|
||||
```
|
||||

|
||||

|
||||
|
||||
#### Badge with fixed color
|
||||
```bash
|
||||
anybadge --label=awesomeness --value="110%" --file=awesomeness.svg --color=#97CA00
|
||||
anybadge --label=awesomeness --value="110%" --file=awesomeness.svg --color='#97CA00'
|
||||
```
|
||||

|
||||

|
||||
|
||||
#### GitLab Scoped style badge
|
||||
```bash
|
||||
anybadge --style=gitlab-scoped --label=Project --value=Archimedes --file=gitlab_scoped.svg --color='#c1115d'
|
||||
```
|
||||

|
||||
|
||||
#### Thresholds based on semantic versions
|
||||
```bash
|
||||
anybadge --label=Version --value=2.4.5 --file=version.svg 1.0.0=red 2.4.6=orange 2.9.1=yellow 999.0.0=green
|
||||
```
|
||||
|
||||
#### Importing in your own app
|
||||
```python
|
||||
from anybadge import Badge
|
||||
|
||||
test1 = Badge(
|
||||
label,
|
||||
value,
|
||||
font_name='DejaVu Sans,Verdana,Geneva,sans-serif',
|
||||
font_size=11,
|
||||
num_padding_chars=0.5,
|
||||
template='<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="{{ badge width }}" height="20">\n <linearGradient id="b" x2="0" y2="100%">\n <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>\n <stop offset="1" stop-opacity=".1"/>\n </linearGradient>\n <mask id="a">\n <rect width="{{ badge width }}" height="20" rx="3" fill="#fff"/>\n </mask>\n <g mask="url(#a)">\n <path fill="#555" d="M0 0h{{ color split x }}v20H0z"/>\n <path fill="{{ color }}" d="M{{ color split x }} 0h{{ value width }}v20H{{ color split x }}z"/>\n <path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>\n </g>\n <g fill="{{ label text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ label anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ label }}</text>\n <text x="{{ label anchor }}" y="14">{{ label }}</text>\n </g>\n <g fill="{{ value text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ value anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ value }}</text>\n <text x="{{ value anchor }}" y="14">{{ value }}</text>\n </g>\n</svg>',
|
||||
value_prefix='',
|
||||
value_suffix='',
|
||||
thresholds=None,
|
||||
default_color='#4c1',
|
||||
use_max_when_value_exceeds=True,
|
||||
value_format=None,
|
||||
text_color='#fff'
|
||||
)
|
||||
|
||||
test1.write_badge('test1.svg')
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
These are the command line options:
|
||||
@@ -273,6 +302,10 @@ optional arguments:
|
||||
Font size.
|
||||
-t TEMPLATE, --template TEMPLATE
|
||||
Location of alternative template .svg file.
|
||||
-s STYLE, --style STYLE
|
||||
Alternative style of badge to create. Valid values are
|
||||
"gitlab-scoped", "default". This overrides any templates
|
||||
passed using --template.
|
||||
-u, --use-max Use the maximum threshold color when the value exceeds
|
||||
the maximum threshold.
|
||||
-f FILE, --file FILE Output file location.
|
||||
@@ -281,6 +314,8 @@ optional arguments:
|
||||
Text color. Single value affects both labeland value
|
||||
colors. A comma separated pair affects label and value
|
||||
text respectively.
|
||||
```
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
@@ -289,22 +324,29 @@ thresholds.
|
||||
|
||||
Pylint::
|
||||
|
||||
```
|
||||
anybadge.py --value=2.22 --file=pylint.svg pylint
|
||||
anybadge.py --label=pylint --value=2.22 --file=pylint.svg 2=red 4=orange 8=yellow 10=green
|
||||
```
|
||||
|
||||
Coverage::
|
||||
|
||||
```
|
||||
anybadge.py --value=65 --file=coverage.svg coverage
|
||||
anybadge.py --label=coverage --value=65 --suffix='%%' --file=coverage.svg 50=red 60=orange 80=yellow 100=green
|
||||
```
|
||||
|
||||
CI Pipeline::
|
||||
|
||||
```
|
||||
anybadge.py --label=pipeline --value=passing --file=pipeline.svg passing=green failing=red
|
||||
```
|
||||
|
||||
Python usage
|
||||
============
|
||||
Here is the output of ``help(anybadge)``::
|
||||
|
||||
```
|
||||
Help on module anybadge:
|
||||
|
||||
NAME
|
||||
@@ -317,30 +359,56 @@ DESCRIPTION
|
||||
CLASSES
|
||||
builtins.object
|
||||
Badge
|
||||
|
||||
|
||||
class Badge(builtins.object)
|
||||
| Badge(label, value, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11, num_padding_chars=0.5, template='<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="{{ badge width }}" height="20">\n <linearGradient id="b" x2="0" y2="100%">\n <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>\n <stop offset="1" stop-opacity=".1"/>\n </linearGradient>\n <mask id="a">\n <rect width="{{ badge width }}" height="20" rx="3" fill="#fff"/>\n </mask>\n <g mask="url(#a)">\n <path fill="#555" d="M0 0h{{ color split x }}v20H0z"/>\n <path fill="{{ color }}" d="M{{ color split x }} 0h{{ value width }}v20H{{ color split x }}z"/>\n <path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>\n </g>\n <g fill="{{ label text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ label anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ label }}</text>\n <text x="{{ label anchor }}" y="14">{{ label }}</text>\n </g>\n <g fill="{{ value text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ value anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ value }}</text>\n <text x="{{ value anchor }}" y="14">{{ value }}</text>\n </g>\n</svg>', value_prefix='', value_suffix='', thresholds=None, default_color='#4c1', use_max_when_value_exceeds=True, value_format=None, text_color='#fff')
|
||||
|
|
||||
| Badge(label, value, font_name=None, font_size=None, num_padding_chars=None, num_label_padding_chars=None, num_value_padding_chars=None, template=None, style=None, value_prefix='', value_suffix='', thresholds=None, default_color=None, use_max_when_value_exceeds=True, value_format=None, text_color=None, semver=False)
|
||||
|
|
||||
| Badge class used to generate badges.
|
||||
|
|
||||
|
|
||||
| Args:
|
||||
| label(str): Badge label text.
|
||||
| value(str): Badge value text.
|
||||
| font_name(str, optional): Name of font to use.
|
||||
| font_size(int, optional): Font size.
|
||||
| num_padding_chars(float, optional): Number of padding characters to use to give extra
|
||||
| space around text.
|
||||
| num_label_padding_chars(float, optional): Number of padding characters to use to give extra
|
||||
| space around label text.
|
||||
| num_value_padding_chars(float, optional): Number of padding characters to use to give extra
|
||||
| space around value text.
|
||||
| template(str, optional): String containing the SVG template. This should be valid SVG
|
||||
| file content with place holders for variables to be populated during rendering.
|
||||
| style(str, optional): Style of badge to create. This will make anybadge render a badge in a
|
||||
| different style. Valid values are "gitlab-scoped", "default". Default is "default".
|
||||
| value_prefix(str, optional): Prefix to be placed before value.
|
||||
| value_suffix(str, optional): Suffix to be placed after value.
|
||||
| thresholds(dict, optional): A dictionary containing thresholds used to select badge
|
||||
| color based on the badge value.
|
||||
| default_color(str, optional): Badge color as a name or as an HTML color code.
|
||||
| use_max_when_value_exceeds(bool, optional): Choose whether to use the maximum threshold
|
||||
| value when the badge value exceeds the top threshold. Default is True.
|
||||
| value_format(str, optional) String with formatting to be used to format the value text.
|
||||
| text_color(str, optional): Text color as a name or as an HTML color code.
|
||||
| semver(bool, optional): Used to indicate that the value is a semantic version number.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
|
|
||||
| Create a simple green badge:
|
||||
|
|
||||
|
|
||||
| >>> badge = Badge('label', 123, default_color='green')
|
||||
|
|
||||
|
|
||||
| Write a badge to file, overwriting any existing file:
|
||||
|
|
||||
|
|
||||
| >>> badge = Badge('label', 123, default_color='green')
|
||||
| >>> badge.write_badge('demo.svg', overwrite=True)
|
||||
|
|
||||
|
|
||||
| Here are a number of examples showing thresholds, since there
|
||||
| are certain situations that may not be obvious:
|
||||
|
|
||||
|
|
||||
| >>> badge = Badge('pipeline', 'passing', thresholds={'passing': 'green', 'failing': 'red'})
|
||||
| >>> badge.badge_color
|
||||
| 'green'
|
||||
|
|
||||
|
|
||||
| 2.32 is not <2
|
||||
| 2.32 is < 4, so 2.32 yields orange
|
||||
| >>> badge = Badge('pylint', 2.32, thresholds={2: 'red',
|
||||
@@ -349,7 +417,7 @@ CLASSES
|
||||
| ... 10: 'green'})
|
||||
| >>> badge.badge_color
|
||||
| 'orange'
|
||||
|
|
||||
|
|
||||
| 8 is not <8
|
||||
| 8 is <4, so 8 yields orange
|
||||
| >>> badge = Badge('pylint', 8, thresholds={2: 'red',
|
||||
@@ -358,7 +426,7 @@ CLASSES
|
||||
| ... 10: 'green'})
|
||||
| >>> badge.badge_color
|
||||
| 'green'
|
||||
|
|
||||
|
|
||||
| 10 is not <8, but use_max_when_value_exceeds defaults to
|
||||
| True, so 10 yields green
|
||||
| >>> badge = Badge('pylint', 11, thresholds={2: 'red',
|
||||
@@ -367,7 +435,7 @@ CLASSES
|
||||
| ... 10: 'green'})
|
||||
| >>> badge.badge_color
|
||||
| 'green'
|
||||
|
|
||||
|
|
||||
| 11 is not <10, and use_max_when_value_exceeds is set to
|
||||
| False, so 11 yields the default color '#4c1'
|
||||
| >>> badge = Badge('pylint', 11, use_max_when_value_exceeds=False,
|
||||
@@ -375,149 +443,229 @@ CLASSES
|
||||
| ... 10: 'green'})
|
||||
| >>> badge.badge_color
|
||||
| '#4c1'
|
||||
|
|
||||
|
|
||||
| Methods defined here:
|
||||
|
|
||||
| __init__(self, label, value, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11, num_padding_chars=0.5, template='<?xml version="1.0" encoding="UTF-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" width="{{ badge width }}" height="20">\n <linearGradient id="b" x2="0" y2="100%">\n <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>\n <stop offset="1" stop-opacity=".1"/>\n </linearGradient>\n <mask id="a">\n <rect width="{{ badge width }}" height="20" rx="3" fill="#fff"/>\n </mask>\n <g mask="url(#a)">\n <path fill="#555" d="M0 0h{{ color split x }}v20H0z"/>\n <path fill="{{ color }}" d="M{{ color split x }} 0h{{ value width }}v20H{{ color split x }}z"/>\n <path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>\n </g>\n <g fill="{{ label text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ label anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ label }}</text>\n <text x="{{ label anchor }}" y="14">{{ label }}</text>\n </g>\n <g fill="{{ value text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">\n <text x="{{ value anchor shadow }}" y="15" fill="#010101" fill-opacity=".3">{{ value }}</text>\n <text x="{{ value anchor }}" y="14">{{ value }}</text>\n </g>\n</svg>', value_prefix='', value_suffix='', thresholds=None, default_color='#4c1', use_max_when_value_exceeds=True, value_format=None, text_color='#fff')
|
||||
|
|
||||
| __init__(self, label, value, font_name=None, font_size=None, num_padding_chars=None, num_label_padding_chars=None, num_value_padding_chars=None, template=None, style=None, value_prefix='', value_suffix='', thresholds=None, default_color=None, use_max_when_value_exceeds=True, value_format=None, text_color=None, semver=False)
|
||||
| Constructor for Badge class.
|
||||
|
|
||||
|
|
||||
| __repr__(self)
|
||||
| Return a representation of the Badge object instance.
|
||||
|
|
||||
| The output of the __repr__ function could be used to recreate the current object.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| >>> badge = Badge('example', '123.456')
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123.456')"
|
||||
|
|
||||
| >>> badge = Badge('example', '123.456', value_suffix='TB')
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123.456', value_suffix='TB')"
|
||||
|
|
||||
| >>> badge = Badge('example', '123.456', text_color='#111111', value_suffix='TB')
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123.456', value_suffix='TB', text_color='#111111')"
|
||||
|
|
||||
| >>> badge = Badge('example', '123', num_padding_chars=5)
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123', num_padding_chars=5)"
|
||||
|
|
||||
| >>> badge = Badge('example', '123', num_label_padding_chars=5)
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123', num_label_padding_chars=5)"
|
||||
|
|
||||
| >>> badge = Badge('example', '123', num_label_padding_chars=5, num_value_padding_chars=6,
|
||||
| ... template='template.svg', value_prefix='$', thresholds={10: 'green', 30: 'red'},
|
||||
| ... default_color='red', use_max_when_value_exceeds=False, value_format="%s m/s")
|
||||
| >>> repr(badge)
|
||||
| "Badge('example', '123', num_label_padding_chars=5, num_value_padding_chars=6, template='template.svg', value_prefix='$', thresholds={10: 'green', 30: 'red'}, default_color='red', use_max_when_value_exceeds=False, value_format='%s m/s')"
|
||||
|
|
||||
| __str__(self)
|
||||
| Return string representation of badge.
|
||||
|
|
||||
| This will return the badge SVG text.
|
||||
|
|
||||
| Returns: str
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| >>> print(Badge('example', '123')) # doctest: +ELLIPSIS
|
||||
| <?xml version="1.0" encoding="UTF-8"?>
|
||||
| ...
|
||||
|
|
||||
| get_text_width(self, text)
|
||||
| Return the width of text.
|
||||
|
|
||||
|
|
||||
| Args:
|
||||
| text(str): Text to get the pixel width of.
|
||||
|
|
||||
|
|
||||
| Returns:
|
||||
| int: Pixel width of the given text based on the badges selected font.
|
||||
|
|
||||
|
|
||||
| This implementation assumes a fixed font of:
|
||||
|
|
||||
|
|
||||
| font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"
|
||||
| >>> badge = Badge('x', 1, font_name='DejaVu Sans,Verdana,Geneva,sans-serif', font_size=11)
|
||||
| >>> badge.get_text_width('pylint')
|
||||
| 34
|
||||
|
|
||||
|
|
||||
| write_badge(self, file_path, overwrite=False)
|
||||
| Write badge to file.
|
||||
|
|
||||
|
|
||||
| ----------------------------------------------------------------------
|
||||
| Data descriptors defined here:
|
||||
|
|
||||
| __dict__
|
||||
| dictionary for instance variables (if defined)
|
||||
|
|
||||
| __weakref__
|
||||
| list of weak references to the object (if defined)
|
||||
|
|
||||
| Readonly properties defined here:
|
||||
|
|
||||
| arc_start
|
||||
| The position where the arc on the gitlab-scoped should start.
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| >>> badge = Badge('pylint', '5')
|
||||
| >>> badge.arc_start
|
||||
| 58
|
||||
|
|
||||
| badge_color
|
||||
| Badge color based on the configured thresholds.
|
||||
|
|
||||
|
|
||||
| Returns: str
|
||||
|
|
||||
|
|
||||
| badge_color_code
|
||||
| Return the color code for the badge.
|
||||
|
|
||||
|
|
||||
| Returns: str
|
||||
|
|
||||
|
|
||||
| Raises: ValueError when an invalid badge color is set.
|
||||
|
|
||||
| badge_svg_text
|
||||
| The badge SVG text.
|
||||
|
|
||||
|
|
||||
| Returns: str
|
||||
|
|
||||
|
|
||||
| badge_width
|
||||
| The total width of badge.
|
||||
|
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
|
|
||||
| >>> badge = Badge('pylint', '5')
|
||||
| >>> badge.badge_width
|
||||
| 103
|
||||
|
|
||||
| 61
|
||||
|
|
||||
| color_split_position
|
||||
| The SVG x position where the color split should occur.
|
||||
|
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
|
|
||||
| float_thresholds
|
||||
| Thresholds as a dict using floats as keys.
|
||||
|
|
||||
| font_width
|
||||
| Return the width multiplier for a font.
|
||||
|
|
||||
|
|
||||
| Returns:
|
||||
| int: Maximum pixel width of badges selected font.
|
||||
|
|
||||
|
|
||||
| Example:
|
||||
|
|
||||
|
|
||||
| >>> Badge(label='x', value='1').font_width
|
||||
| 10
|
||||
|
|
||||
|
|
||||
| label_anchor
|
||||
| The SVG x position of the middle anchor for the label text.
|
||||
|
|
||||
|
|
||||
| Returns: float
|
||||
|
|
||||
|
|
||||
| label_anchor_shadow
|
||||
| The SVG x position of the label shadow anchor.
|
||||
|
|
||||
|
|
||||
| Returns: float
|
||||
|
|
||||
|
|
||||
| label_width
|
||||
| The SVG width of the label text.
|
||||
|
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
|
|
||||
| semver_thresholds
|
||||
| Thresholds as a dict using LooseVersion as keys.
|
||||
|
|
||||
| semver_version
|
||||
| The semantic version represented by the value string.
|
||||
|
|
||||
| Returns: LooseVersion
|
||||
|
|
||||
| value_anchor
|
||||
| The SVG x position of the middle anchor for the value text.
|
||||
|
|
||||
|
|
||||
| Returns: float
|
||||
|
|
||||
|
|
||||
| value_anchor_shadow
|
||||
| The SVG x position of the value shadow anchor.
|
||||
|
|
||||
|
|
||||
| Returns: float
|
||||
|
|
||||
|
|
||||
| value_box_width
|
||||
| The SVG width of the value text box.
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
| value_is_float
|
||||
| Identify whether the value text is a float.
|
||||
|
|
||||
|
|
||||
| Returns: bool
|
||||
|
|
||||
|
|
||||
| value_is_int
|
||||
| Identify whether the value text is an int.
|
||||
|
|
||||
|
|
||||
| Returns: bool
|
||||
|
|
||||
|
|
||||
| value_type
|
||||
| The Python type associated with the value.
|
||||
|
|
||||
|
|
||||
| Returns: type
|
||||
|
|
||||
|
|
||||
| value_width
|
||||
| The SVG width of the value text.
|
||||
|
|
||||
|
|
||||
| Returns: int
|
||||
|
|
||||
| ----------------------------------------------------------------------
|
||||
| Data descriptors defined here:
|
||||
|
|
||||
| __dict__
|
||||
| dictionary for instance variables (if defined)
|
||||
|
|
||||
| __weakref__
|
||||
| list of weak references to the object (if defined)
|
||||
|
||||
FUNCTIONS
|
||||
main()
|
||||
main(args=None)
|
||||
Generate a badge based on command line arguments.
|
||||
|
||||
parse_args()
|
||||
|
||||
parse_args(args)
|
||||
Parse the command line arguments.
|
||||
|
||||
DATA
|
||||
BADGE_TEMPLATES = {'coverage': {'label': 'coverage', 'suffix': '%', 't...
|
||||
COLORS = {'green': '#4c1', 'lightgrey': '#9f9f9f', 'orange': '#fe7d37'...
|
||||
COLORS = {'aqua': '#00FFFF', 'black': '#000000', 'blue': '#0000FF', 'b...
|
||||
DEFAULT_COLOR = '#4c1'
|
||||
DEFAULT_FONT = 'DejaVu Sans,Verdana,Geneva,sans-serif'
|
||||
DEFAULT_FONT_SIZE = 11
|
||||
DEFAULT_TEXT_COLOR = '#fff'
|
||||
FONT_WIDTHS = {'DejaVu Sans,Verdana,Geneva,sans-serif': {11: 10}}
|
||||
FONT_WIDTHS = {'Arial, Helvetica, sans-serif': {11: 8}, 'DejaVu Sans,V...
|
||||
MASK_ID_PREFIX = 'anybadge_'
|
||||
NUM_PADDING_CHARS = 0.5
|
||||
TEMPLATE_GITLAB_SCOPED_SVG = '<?xml version="1.0" encoding="UTF-8"?>\n...
|
||||
TEMPLATE_SVG = '<?xml version="1.0" encoding="UTF-8"?>\n<svg xmln...ho...
|
||||
VERSION_COMPARISON_SUPPORTED = True
|
||||
__summary__ = 'A simple, flexible badge generator.'
|
||||
__title__ = 'anybadge'
|
||||
__uri__ = 'https://github.com/jongracecox/anybadge'
|
||||
__version_info__ = ('0', '0', '0')
|
||||
digits = '0123456789'
|
||||
version = '0.0.0'
|
||||
|
||||
VERSION
|
||||
|
||||
96
anybadge.py
96
anybadge.py
@@ -101,6 +101,31 @@ TEMPLATE_SVG = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
</g>
|
||||
</svg>"""
|
||||
|
||||
# Template SVG for GitLab Scoped label and value badges with placeholders for
|
||||
# various items that will be added during final creation.
|
||||
TEMPLATE_GITLAB_SCOPED_SVG = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="{{ badge width }}" height="20">
|
||||
<linearGradient id="b" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<mask id="{{ mask id }}">
|
||||
<rect width="{{ badge width }}" height="20" rx="10" fill="#fff"/>
|
||||
</mask>
|
||||
<g mask="url(#{{ mask id }})">
|
||||
<path fill="{{ color }}" d="M0 0h{{ badge width }}v20H0z"/>
|
||||
<path fill="#262626" d="M{{ color split x }} 2h{{ value box width }}v16H{{ color split x }}z"/>
|
||||
<path fill="#262626" d="M{{ arc start }},18 a1,1 0 0,0 0,-16"/>
|
||||
<path fill="url(#b)" d="M0 0h{{ badge width }}v20H0z"/>
|
||||
</g>
|
||||
<g fill="{{ label text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">
|
||||
<text x="{{ label anchor }}" y="14">{{ label }}</text>
|
||||
</g>
|
||||
<g fill="{{ value text color }}" text-anchor="middle" font-family="{{ font name }}" font-size="{{ font size }}">
|
||||
<text x="{{ value anchor }}" y="14">{{ value }}</text>
|
||||
</g>
|
||||
</svg>"""
|
||||
|
||||
# Define some templates that can be used for common badge types, saving
|
||||
# from having to provide thresholds and labels each time.
|
||||
BADGE_TEMPLATES = {
|
||||
@@ -133,6 +158,8 @@ class Badge(object):
|
||||
space around value text.
|
||||
template(str, optional): String containing the SVG template. This should be valid SVG
|
||||
file content with place holders for variables to be populated during rendering.
|
||||
style(str, optional): Style of badge to create. This will make anybadge render a badge in a
|
||||
different style. Valid values are "gitlab-scoped", "default". Default is "default".
|
||||
value_prefix(str, optional): Prefix to be placed before value.
|
||||
value_suffix(str, optional): Suffix to be placed after value.
|
||||
thresholds(dict, optional): A dictionary containing thresholds used to select badge
|
||||
@@ -200,7 +227,7 @@ class Badge(object):
|
||||
|
||||
def __init__(self, label, value, font_name=None, font_size=None,
|
||||
num_padding_chars=None, num_label_padding_chars=None,
|
||||
num_value_padding_chars=None, template=None,
|
||||
num_value_padding_chars=None, template=None, style=None,
|
||||
value_prefix='', value_suffix='', thresholds=None, default_color=None,
|
||||
use_max_when_value_exceeds=True, value_format=None, text_color=None,
|
||||
semver=False):
|
||||
@@ -222,6 +249,8 @@ class Badge(object):
|
||||
num_value_padding_chars = num_padding_chars
|
||||
if not template:
|
||||
template = TEMPLATE_SVG
|
||||
if style not in ['gitlab-scoped']:
|
||||
style = "default"
|
||||
if not default_color:
|
||||
default_color = DEFAULT_COLOR
|
||||
if not text_color:
|
||||
@@ -250,6 +279,7 @@ class Badge(object):
|
||||
self.num_label_padding_chars = num_label_padding_chars
|
||||
self.num_value_padding_chars = num_value_padding_chars
|
||||
self.template = template
|
||||
self.style = style
|
||||
self.thresholds = thresholds
|
||||
self.default_color = default_color
|
||||
|
||||
@@ -313,6 +343,8 @@ class Badge(object):
|
||||
optional_args += ", num_value_padding_chars=%s" % repr(self.num_value_padding_chars)
|
||||
if self.template != TEMPLATE_SVG:
|
||||
optional_args += ", template=%s" % repr(self.template)
|
||||
if self.style != 'default':
|
||||
optional_args += ", style=%s" % repr(self.style)
|
||||
if self.value_prefix != '':
|
||||
optional_args += ", value_prefix=%s" % repr(self.value_prefix)
|
||||
if self.value_suffix != '':
|
||||
@@ -337,13 +369,13 @@ class Badge(object):
|
||||
|
||||
def _repr_svg_(self):
|
||||
"""Return SVG representation when used inside Jupyter notebook cells.
|
||||
|
||||
|
||||
This will render the SVG immediately inside a notebook cell when creating
|
||||
a Badge instance without assigning it to an identifier.
|
||||
"""
|
||||
return self.badge_svg_text
|
||||
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def _get_next_mask_id(cls):
|
||||
"""Return a new mask ID from a singleton sequence maintained on the class.
|
||||
@@ -357,6 +389,22 @@ class Badge(object):
|
||||
|
||||
return MASK_ID_PREFIX + str(cls.mask_id)
|
||||
|
||||
def _get_svg_template(self):
|
||||
"""Return the correct SVG template to render, based on the style and template
|
||||
that have been set
|
||||
|
||||
Returns: str
|
||||
"""
|
||||
if self.style == "gitlab-scoped":
|
||||
return TEMPLATE_GITLAB_SCOPED_SVG
|
||||
|
||||
# Identify whether template is a file or the actual template text
|
||||
if len(self.template.split('\n')) == 1:
|
||||
with open(self.template, mode='r') as file_handle:
|
||||
return file_handle.read()
|
||||
else:
|
||||
return self.template
|
||||
|
||||
@property
|
||||
def semver_version(self):
|
||||
"""The semantic version represented by the value string.
|
||||
@@ -443,6 +491,14 @@ class Badge(object):
|
||||
"""
|
||||
return int(self.get_text_width(str(self.value_text)) + (2.0 * self.num_value_padding_chars * self.font_width))
|
||||
|
||||
@property
|
||||
def value_box_width(self):
|
||||
"""The SVG width of the value text box.
|
||||
|
||||
Returns: int
|
||||
"""
|
||||
return self.value_width - 9
|
||||
|
||||
@property
|
||||
def font_width(self):
|
||||
"""Return the width multiplier for a font.
|
||||
@@ -511,6 +567,20 @@ class Badge(object):
|
||||
"""
|
||||
return self.label_width + self.value_width
|
||||
|
||||
@property
|
||||
def arc_start(self):
|
||||
"""The position where the arc on the gitlab-scoped should start.
|
||||
|
||||
Returns: int
|
||||
|
||||
Examples:
|
||||
|
||||
>>> badge = Badge('pylint', '5')
|
||||
>>> badge.arc_start
|
||||
51
|
||||
"""
|
||||
return self.badge_width - 10
|
||||
|
||||
@property
|
||||
def badge_svg_text(self):
|
||||
"""The badge SVG text.
|
||||
@@ -518,12 +588,7 @@ class Badge(object):
|
||||
Returns: str
|
||||
"""
|
||||
|
||||
# Identify whether template is a file or the actual template text
|
||||
if len(self.template.split('\n')) == 1:
|
||||
with open(self.template, mode='r') as file_handle:
|
||||
badge_text = file_handle.read()
|
||||
else:
|
||||
badge_text = self.template
|
||||
badge_text = self._get_svg_template()
|
||||
|
||||
return badge_text.replace('{{ badge width }}', str(self.badge_width)) \
|
||||
.replace('{{ font name }}', self.font_name) \
|
||||
@@ -538,8 +603,10 @@ class Badge(object):
|
||||
.replace('{{ label text color }}', self.label_text_color) \
|
||||
.replace('{{ value text color }}', self.value_text_color) \
|
||||
.replace('{{ color split x }}', str(self.color_split_position)) \
|
||||
.replace('{{ value width }}', str(self.value_width))\
|
||||
.replace('{{ mask id }}', self.mask_id)
|
||||
.replace('{{ value width }}', str(self.value_width)) \
|
||||
.replace('{{ mask id }}', self.mask_id) \
|
||||
.replace('{{ value box width }}', str(self.value_box_width)) \
|
||||
.replace('{{ arc start }}', str(self.arc_start))
|
||||
|
||||
def __str__(self):
|
||||
"""Return string representation of badge.
|
||||
@@ -824,6 +891,9 @@ examples:
|
||||
parser.add_argument('-t', '--template', type=str, help='Location of alternative '
|
||||
'template .svg file.',
|
||||
default=TEMPLATE_SVG)
|
||||
parser.add_argument('-st', '--style', type=str, help='Alternative style of badge to create. Valid '
|
||||
'values are "gitlab-scoped", "default". This '
|
||||
'overrides any templates passed using --template.')
|
||||
parser.add_argument('-u', '--use-max', action='store_true',
|
||||
help='Use the maximum threshold color when the value exceeds the '
|
||||
'maximum threshold.')
|
||||
@@ -878,7 +948,7 @@ def main(args=None):
|
||||
badge = Badge(label, args.value, value_prefix=args.prefix, value_suffix=suffix,
|
||||
default_color=args.color, num_padding_chars=args.padding,
|
||||
num_label_padding_chars=args.label_padding, num_value_padding_chars=args.value_padding,
|
||||
font_name=args.font, font_size=args.font_size, template=args.template,
|
||||
font_name=args.font, font_size=args.font_size, template=args.template, style=args.style,
|
||||
use_max_when_value_exceeds=args.use_max, thresholds=threshold_dict,
|
||||
value_format=args.value_format, text_color=args.text_color, semver=args.semver)
|
||||
|
||||
|
||||
22
examples/gitlab_scoped.svg
Normal file
22
examples/gitlab_scoped.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="132" height="20">
|
||||
<linearGradient id="b" x2="0" y2="100%">
|
||||
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
||||
<stop offset="1" stop-opacity=".1"/>
|
||||
</linearGradient>
|
||||
<mask id="anybadge_1">
|
||||
<rect width="132" height="20" rx="10" fill="#fff"/>
|
||||
</mask>
|
||||
<g mask="url(#anybadge_1)">
|
||||
<path fill="#c1115d" d="M0 0h132v20H0z"/>
|
||||
<path fill="#262626" d="M53 2h70v16H53z"/>
|
||||
<path fill="#262626" d="M122,18 a1,1 0 0,0 0,-16"/>
|
||||
<path fill="url(#b)" d="M0 0h132v20H0z"/>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="26.5" y="14">Project</text>
|
||||
</g>
|
||||
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
||||
<text x="91.5" y="14">Archimedes</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 963 B |
Reference in New Issue
Block a user