Test Failed
Pull Request — master (#2)
by Heiko 'riot'
06:45
created

isomer.misc.std.std_table()   C

Complexity

Conditions 10

Size

Total Lines 34
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 28
nop 1
dl 0
loc 34
rs 5.9999
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like isomer.misc.std.std_table() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
4
# Isomer - The distributed application framework
5
# ==============================================
6
# Copyright (C) 2011-2020 Heiko 'riot' Weinen <[email protected]> and others.
7
#
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU Affero General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
12
#
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU Affero General Public License for more details.
17
#
18
# You should have received a copy of the GNU Affero General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
"""
22
Miscellaneous standard functions for Isomer
23
"""
24
25
import SecretColors
26
import bcrypt
27
import pytz
28
29
from datetime import datetime
30
from random import choice
31
from typing import AnyStr, Optional
32
from uuid import uuid4
33
34
from isomer.logger import isolog, warn
35
36
37
def std_salt() -> str:
38
    """Generates a secure cryptographical salt
39
    """
40
41
    return bcrypt.gensalt().decode("utf-8")
42
43
44
def std_hash(word: AnyStr, salt: AnyStr):
45
    """Generates a cryptographically strong (bcrypt) password hash with a given
46
    salt added."""
47
48
    try:
49
        password: bytes = word.encode("utf-8")
50
    except UnicodeDecodeError:
51
        password = word
52
53
    if isinstance(salt, str):
54
        salt_bytes = salt.encode("utf-8")
55
    else:
56
        salt_bytes = salt
57
58
    password_hash = bcrypt.hashpw(password, salt_bytes).decode("ascii")
59
60
    return password_hash
61
62
63
def std_now(delta=None, date_format="iso", tz="UTC"):
64
    """Return current timestamp in ISO format"""
65
66
    now = datetime.now(tz=pytz.timezone(tz))
67
68
    if delta is not None:
69
        now = now + delta
70
71
    if date_format == "iso":
72
        result = now.isoformat()
73
    elif date_format == "germandate":
74
        result = now.strftime("%d.%m.%Y")
75
    else:
76
        result = now
77
78
    return result
79
80
81
def std_datetime(date, date_format="%d.%m.%Y", tz="UTC"):
82
    """Return something that looks like a date into a timestamp in ISO format"""
83
84
    if isinstance(date, tuple):
85
        now = datetime(*date)
86
    elif isinstance(date, str):
87
        if date_format == 'iso':
88
            now = datetime.fromisoformat(date)
89
        else:
90
            now = datetime.strptime(date, date_format)
91
92
    else:
93
        isolog("Could not convert date:", date, date_format, tz, pretty=True, lvl=warn)
94
        return date
95
96
    now = now.astimezone(pytz.timezone(tz))
97
98
    result = now.isoformat()
99
100
    return result
101
102
103
def std_uuid():
104
    """Return string representation of a new UUID4"""
105
106
    return str(uuid4())
107
108
109
def std_color(palette_name=None):
110
    """Generate random default color"""
111
    if palette_name is None:
112
        palette_name = "ibm"
113
114
    color = SecretColors.Palette(palette_name, show_warning=False).random()
115
    return color
116
117
118
# def std_human_uid(kind: Literal['animal', 'place', 'color'] = None) -> str:
119
def std_human_uid(kind: Optional[str] = None) -> str:
120
    """Return a random generated human-friendly phrase as low-probability unique id
121
122
    :param kind: Specify the type of id (animal, place, color or None)
123
    :return: Human readable ID
124
    :rtype: str
125
    """
126
127
    kind_list = radio_alphabet
128
129
    if kind == "animal":
130
        kind_list = animals
131
    elif kind == "place":
132
        kind_list = places
133
134
    name = "{color} {adjective} {kind} of {attribute}".format(
135
        color=choice(colors),
136
        adjective=choice(adjectives),
137
        kind=choice(kind_list),
138
        attribute=choice(attributes),
139
    )
140
141
    return name
142
143
144
def std_table(rows):
145
    """Return a formatted table of given rows"""
146
147
    result = ""
148
    if len(rows) > 1:
149
        headers = rows[0]._fields
150
        lens = []
151
        for i in range(len(rows[0])):
152
            lens.append(
153
                len(max([x[i] for x in rows] + [headers[i]], key=lambda x: len(str(x))))
154
            )
155
        formats = []
156
        hformats = []
157
        for i in range(len(rows[0])):
158
            if isinstance(rows[0][i], int):
159
                formats.append("%%%dd" % lens[i])
160
            else:
161
                formats.append("%%-%ds" % lens[i])
162
            hformats.append("%%-%ds" % lens[i])
163
        pattern = " | ".join(formats)
164
        hpattern = " | ".join(hformats)
165
        separator = "-+-".join(["-" * n for n in lens])
166
        result += hpattern % tuple(headers) + " \n"
167
        result += separator + "\n"
168
169
        for line in rows:
170
            result += pattern % tuple(t for t in line) + "\n"
171
    elif len(rows) == 1:
172
        row = rows[0]
173
        hwidth = len(max(row._fields, key=lambda x: len(x)))
174
        for i in range(len(row)):
175
            result += "%*s = %s" % (hwidth, row._fields[i], row[i]) + "\n"
176
177
    return result
178
179
180
colors = ["Red", "Orange", "Yellow", "Green", "Cyan", "Blue", "Violet", "Purple"]
181
adjectives = [
182
    "abundant",
183
    "adorable",
184
    "agreeable",
185
    "alive",
186
    "ancient",
187
    "angry",
188
    "beautiful",
189
    "better",
190
    "bewildered",
191
    "big",
192
    "bitter",
193
    "boiling",
194
    "brave",
195
    "breeze",
196
    "brief",
197
    "broad",
198
    "broken",
199
    "bumpy",
200
    "calm",
201
    "careful",
202
    "chilly",
203
    "chubby",
204
    "circular",
205
    "clean",
206
    "clever",
207
    "clumsy",
208
    "cold",
209
    "colossal",
210
    "cooing",
211
    "cool",
212
    "creepy",
213
    "crooked",
214
    "cuddly",
215
    "curly",
216
    "curved",
217
    "damaged",
218
    "damp",
219
    "deafening",
220
    "deep",
221
    "defeated",
222
    "delicious",
223
    "delightful",
224
    "dirty",
225
    "drab",
226
    "dry",
227
    "dusty",
228
    "eager",
229
    "early",
230
    "easy",
231
    "elegant",
232
    "embarrassed",
233
    "empty",
234
    "faint",
235
    "faithful",
236
    "famous",
237
    "fancy",
238
    "fast",
239
    "fat",
240
    "few",
241
    "fierce",
242
    "flaky",
243
    "flat",
244
    "fluffy",
245
    "freezing",
246
    "fresh",
247
    "full",
248
    "gentle",
249
    "gifted",
250
    "gigantic",
251
    "glamorous",
252
    "greasy",
253
    "great",
254
    "grumpy",
255
    "handsome",
256
    "happy",
257
    "heavy",
258
    "helpful",
259
    "helpless",
260
    "high",
261
    "hissing",
262
    "hollow",
263
    "hot",
264
    "huge",
265
    "icy",
266
    "immense",
267
    "important",
268
    "inexpensive",
269
    "itchy",
270
    "jealous",
271
    "jolly",
272
    "juicy",
273
    "kind",
274
    "large",
275
    "late",
276
    "lazy",
277
    "light",
278
    "little",
279
    "lively",
280
    "long",
281
    "loose",
282
    "loud",
283
    "low",
284
    "magnificent",
285
    "mammoth",
286
    "many",
287
    "massive",
288
    "melodic",
289
    "melted",
290
    "miniature",
291
    "modern",
292
    "mushy",
293
    "mysterious",
294
    "narrow",
295
    "nervous",
296
    "nice",
297
    "noisy",
298
    "numerous",
299
    "nutritious",
300
    "obedient",
301
    "obnoxious",
302
    "odd",
303
    "old",
304
    "old-fashioned",
305
    "panicky",
306
    "petite",
307
    "plain",
308
    "powerful",
309
    "prickly",
310
    "proud",
311
    "puny",
312
    "purring",
313
    "quaint",
314
    "quick",
315
    "quiet",
316
    "rainy",
317
    "rapid",
318
    "raspy",
319
    "relieved",
320
    "rich",
321
    "round",
322
    "salty",
323
    "scary",
324
    "scrawny",
325
    "screeching",
326
    "shallow",
327
    "short",
328
    "shy",
329
    "silly",
330
    "skinny",
331
    "slow",
332
    "small",
333
    "sparkling",
334
    "sparse",
335
    "square",
336
    "steep",
337
    "sticky",
338
    "straight",
339
    "strong",
340
    "substantial",
341
    "sweet",
342
    "swift",
343
    "tall",
344
    "tart",
345
    "tasteless",
346
    "teeny",
347
    "tiny",
348
    "tender",
349
    "thankful",
350
    "thoughtless",
351
    "thundering",
352
    "uneven",
353
    "uninterested",
354
    "unsightly",
355
    "uptight",
356
    "vast",
357
    "victorious",
358
    "voiceless",
359
    "warm",
360
    "weak",
361
    "wet",
362
    "wet",
363
    "whispering",
364
    "wide",
365
    "wide-eyed",
366
    "witty",
367
    "wooden",
368
    "worried",
369
    "wrong",
370
    "young",
371
    "yummy",
372
    "zealous",
373
]
374
animals = [
375
    "Aardvark",
376
    "Abyssinian",
377
    "Affenpinscher",
378
    "Akbash",
379
    "Akita",
380
    "Albatross",
381
    "Alligator",
382
    "Angelfish",
383
    "Ant",
384
    "Anteater",
385
    "Antelope",
386
    "Armadillo",
387
    "Avocet",
388
    "Axolotl",
389
    "Baboon",
390
    "Badger",
391
    "Balinese",
392
    "Bandicoot",
393
    "Barb",
394
    "Barnacle",
395
    "Barracuda",
396
    "Bat",
397
    "Beagle",
398
    "Bear",
399
    "Beaver",
400
    "Beetle",
401
    "Binturong",
402
    "Bird",
403
    "Birman",
404
    "Bison",
405
    "Bloodhound",
406
    "Bobcat",
407
    "Bombay",
408
    "Bongo",
409
    "Bonobo",
410
    "Booby",
411
    "Budgerigar",
412
    "Buffalo",
413
    "Bulldog",
414
    "Bullfrog",
415
    "Burmese",
416
    "Butterfly",
417
    "Caiman",
418
    "Camel",
419
    "Capybara",
420
    "Caracal",
421
    "Cassowary",
422
    "Cat",
423
    "Caterpillar",
424
    "Catfish",
425
    "Centipede",
426
    "Chameleon",
427
    "Chamois",
428
    "Cheetah",
429
    "Chicken",
430
    "Chihuahua",
431
    "Chimpanzee",
432
    "Chinchilla",
433
    "Chinook",
434
    "Chipmunk",
435
    "Cichlid",
436
    "Coati",
437
    "Cockroach",
438
    "Collie",
439
    "Coral",
440
    "Cougar",
441
    "Cow",
442
    "Coyote",
443
    "Crab",
444
    "Crane",
445
    "Crocodile",
446
    "Cuscus",
447
    "Cuttlefish",
448
    "Dachshund",
449
    "Dalmatian",
450
    "Deer",
451
    "Dhole",
452
    "Dingo",
453
    "Discus",
454
    "Dodo",
455
    "Dog",
456
    "Dolphin",
457
    "Donkey",
458
    "Dormouse",
459
    "Dragonfly",
460
    "Drever",
461
    "Duck",
462
    "Dugong",
463
    "Dunker",
464
    "Eagle",
465
    "Earwig",
466
    "Echidna",
467
    "Elephant",
468
    "Emu",
469
    "Falcon",
470
    "Ferret",
471
    "Fish",
472
    "Flamingo",
473
    "Flounder",
474
    "Fly",
475
    "Fossa",
476
    "Fox",
477
    "Frigatebird",
478
    "Frog",
479
    "Gar",
480
    "Gecko",
481
    "Gerbil",
482
    "Gharial",
483
    "Gibbon",
484
    "Giraffe",
485
    "Goat",
486
    "Goose",
487
    "Gopher",
488
    "Gorilla",
489
    "Grasshopper",
490
    "Greyhound",
491
    "Grouse",
492
    "Guppy",
493
    "Hamster",
494
    "Hare",
495
    "Harrier",
496
    "Havanese",
497
    "Hedgehog",
498
    "Heron",
499
    "Himalayan",
500
    "Hippopotamus",
501
    "Horse",
502
    "Human",
503
    "Hummingbird",
504
    "Hyena",
505
    "Ibis",
506
    "Iguana",
507
    "Impala",
508
    "Indri",
509
    "Insect",
510
    "Jackal",
511
    "Jaguar",
512
    "Javanese",
513
    "Jellyfish",
514
    "Kakapo",
515
    "Kangaroo",
516
    "Kingfisher",
517
    "Kiwi",
518
    "Koala",
519
    "Kudu",
520
    "Labradoodle",
521
    "Ladybird",
522
    "Lemming",
523
    "Lemur",
524
    "Leopard",
525
    "Liger",
526
    "Lion",
527
    "Lionfish",
528
    "Lizard",
529
    "Llama",
530
    "Lobster",
531
    "Lynx",
532
    "Macaw",
533
    "Magpie",
534
    "Maltese",
535
    "Manatee",
536
    "Mandrill",
537
    "Markhor",
538
    "Mastiff",
539
    "Mayfly",
540
    "Meerkat",
541
    "Millipede",
542
    "Mole",
543
    "Molly",
544
    "Mongoose",
545
    "Mongrel",
546
    "Monkey",
547
    "Moorhen",
548
    "Moose",
549
    "Moth",
550
    "Mouse",
551
    "Mule",
552
    "Newfoundland",
553
    "Newt",
554
    "Nightingale",
555
    "Numbat",
556
    "Ocelot",
557
    "Octopus",
558
    "Okapi",
559
    "Olm",
560
    "Opossum",
561
    "Orang-utan",
562
    "Ostrich",
563
    "Otter",
564
    "Oyster",
565
    "Pademelon",
566
    "Panther",
567
    "Parrot",
568
    "Peacock",
569
    "Pekingese",
570
    "Pelican",
571
    "Penguin",
572
    "Persian",
573
    "Pheasant",
574
    "Pig",
575
    "Pika",
576
    "Pike",
577
    "Piranha",
578
    "Platypus",
579
    "Pointer",
580
    "Poodle",
581
    "Porcupine",
582
    "Possum",
583
    "Prawn",
584
    "Puffin",
585
    "Pug",
586
    "Puma",
587
    "Quail",
588
    "Quetzal",
589
    "Quokka",
590
    "Quoll",
591
    "Rabbit",
592
    "Raccoon",
593
    "Ragdoll",
594
    "Rat",
595
    "Rattlesnake",
596
    "Reindeer",
597
    "Rhinoceros",
598
    "Robin",
599
    "Rottweiler",
600
    "Salamander",
601
    "Saola",
602
    "Scorpion",
603
    "Seahorse",
604
    "Seal",
605
    "Serval",
606
    "Sheep",
607
    "Shrimp",
608
    "Siamese",
609
    "Siberian",
610
    "Skunk",
611
    "Sloth",
612
    "Snail",
613
    "Snake",
614
    "Snowshoe",
615
    "Somali",
616
    "Sparrow",
617
    "Sponge",
618
    "Squid",
619
    "Squirrel",
620
    "Starfish",
621
    "Stingray",
622
    "Stoat",
623
    "Swan",
624
    "Tang",
625
    "Tapir",
626
    "Tarsier",
627
    "Termite",
628
    "Tetra",
629
    "Tiffany",
630
    "Tiger",
631
    "Tortoise",
632
    "Toucan",
633
    "Tropicbird",
634
    "Tuatara",
635
    "Turkey",
636
    "Uakari",
637
    "Uguisu",
638
    "Umbrellabird",
639
    "Vulture",
640
    "Wallaby",
641
    "Walrus",
642
    "Warthog",
643
    "Wasp",
644
    "Weasel",
645
    "Whippet",
646
    "Wildebeest",
647
    "Wolf",
648
    "Wolverine",
649
    "Wombat",
650
    "Woodlouse",
651
    "Woodpecker",
652
    "Wrasse",
653
    "Yak",
654
    "Zebra",
655
    "Zebu",
656
    "Zonkey",
657
    "Zorse",
658
]
659
radio_alphabet = [
660
    "Alpha",
661
    "Bravo",
662
    "Charlie",
663
    "Delta",
664
    "Echo",
665
    "Foxtrot",
666
    "Golf",
667
    "Hotel",
668
    "India",
669
    "Juliet",
670
    "Kilo",
671
    "Lima",
672
    "Mike",
673
    "November",
674
    "Oscar",
675
    "Papa",
676
    "Quebec",
677
    "Romeo",
678
    "Sierra",
679
    "Tango",
680
    "Uniform",
681
    "Victor",
682
    "Whiskey",
683
    "X-ray",
684
    "Yankee",
685
    "Zulu",
686
]
687
places = [
688
    "airport",
689
    "aquarium",
690
    "bakery",
691
    "bar",
692
    "bridge",
693
    "building",
694
    "bus-stop",
695
    "cafe",
696
    "campground",
697
    "church",
698
    "city",
699
    "embassy",
700
    "florist",
701
    "gym",
702
    "harbour",
703
    "hospital",
704
    "hotel",
705
    "house",
706
    "island",
707
    "laundry",
708
    "library",
709
    "monument",
710
    "mosque",
711
    "museum",
712
    "office",
713
    "park",
714
    "pharmacy",
715
    "plaza",
716
    "restaurant",
717
    "road",
718
    "school",
719
    "spa",
720
    "stable",
721
    "stadium",
722
    "store",
723
    "street",
724
    "theater",
725
    "tower",
726
    "town",
727
    "train-station",
728
    "university",
729
    "village",
730
    "wall",
731
    "zoo",
732
]
733
attributes = [
734
    "Chaos",
735
    "Hate",
736
    "Adventure",
737
    "Anger",
738
    "Anxiety",
739
    "Beauty",
740
    "Beauty",
741
    "Being",
742
    "Beliefs",
743
    "Birthday",
744
    "Brilliance",
745
    "Career",
746
    "Charity",
747
    "Childhood",
748
    "Comfort",
749
    "Communication",
750
    "Confusion",
751
    "Courage",
752
    "Culture",
753
    "Curiosity",
754
    "Death",
755
    "Deceit",
756
    "Dedication",
757
    "Democracy",
758
    "Despair",
759
    "Determination",
760
    "Energy",
761
    "Failure",
762
    "Faith",
763
    "Fear",
764
    "Freedom",
765
    "Friendship",
766
    "Future",
767
    "Generosity",
768
    "Grief",
769
    "Happiness",
770
    "Holiday",
771
    "Honesty",
772
    "Indifference",
773
    "Interest",
774
    "Joy",
775
    "Knowledge",
776
    "Liberty",
777
    "Life",
778
    "Love",
779
    "Luxury",
780
    "Marriage",
781
    "Misery",
782
    "Motivation",
783
    "Nervousness",
784
    "Openness",
785
    "Opportunity",
786
    "Pain",
787
    "Past",
788
    "Patience",
789
    "Peace",
790
    "Perseverance",
791
    "Pessimism",
792
    "Pleasure",
793
    "Sacrifice",
794
    "Sadness",
795
    "Satisfaction",
796
    "Sensitivity",
797
    "Sorrow",
798
    "Stress",
799
    "Sympathy",
800
    "Thought",
801
    "Trust",
802
    "Warmth",
803
    "Wisdom",
804
]
805