Example #1
0
    async def setstrength(self, ctx, *, newstrength):
        """Set your current lift/carry strength."""

        userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True)

        userdata.liftstrength = WV(
            WV.parse(newstrength) * (userdata.viewscale**3))
        userdb.save(userdata)

        await ctx.send(
            f"{userdata.nickname}'s base lift strength is now {userdata.liftstrength:mu} long, "
            f"or {SV(userdata.liftstrength):mu} currently.")
        await showNextStep(ctx, userdata)
Example #2
0
    async def setweight(self, ctx, *, newweight):
        """Set your current weight."""
        userdata = userdb.load(ctx.guild.id, ctx.author.id)

        userdata.baseweight = WV(WV.parse(newweight) * (userdata.viewscale**3))
        userdb.save(userdata)

        logger.info(
            f"User {ctx.author.id} ({ctx.author.display_name}) changed their weight to {newweight}."
        )
        await ctx.send(
            f"<@{ctx.author.id}>'s weight is now {userdata.weight:mu}")

        await proportions.nickUpdate(ctx.author)
Example #3
0
def WV_parse():
    s = request.args.get("s")
    try:
        val = WV.parse(s)
    except InvalidSizeValue:
        abort(404)
    return json.dumps({"WV": str(val)})
Example #4
0
    def __init__(self, userdata):
        self.nickname = userdata.nickname
        self.tag = userdata.tag
        self.gender = userdata.gender
        self.height = userdata.height
        self.baseheight = userdata.baseheight
        self.viewscale = userdata.viewscale
        self.scale = userdata.scale
        self.formattedscale = userdata.getFormattedScale(verbose=True)
        self.baseweight = userdata.baseweight
        self.weight = userdata.weight
        self.formattedweightscale = userdata.getFormattedScale(
            scaletype="weight", verbose=True)

        self.averageheightmult = self.height / defaultheight
        self.averageweightmult = self.weight / defaultweight

        if userdata.hairlength is None:
            self.hairlength = None
        else:
            self.hairlength = SV(userdata.hairlength / self.viewscale)

        if userdata.taillength is None:
            self.taillength = None
        else:
            self.taillength = SV(userdata.taillength / self.viewscale)

        if userdata.footlength is None:
            self.footlength = SV(self.height * self.footfactor)
        else:
            self.footlength = SV(userdata.footlength / self.viewscale)
        self.shoesize = formatShoeSize(self.footlength, self.gender == "f")
        self.footwidth = SV(self.height * self.footwidthfactor)
        self.toeheight = SV(self.height * self.toeheightfactor)
        self.shoeprintdepth = SV(self.height * self.toeheightfactor)
        self.pointerlength = SV(self.height * self.pointerfactor)
        self.thumbwidth = SV(self.height * self.thumbfactor)
        self.fingerprintdepth = SV(self.height * self.fingerprintfactor)

        defaultthreadthickness = SV.parse("1.016mm")
        self.threadthickness = SV(defaultthreadthickness *
                                  self.averageheightmult)

        self.hairwidth = SV(self.height * self.hairfactor)
        self.nailthickness = SV(self.height * self.nailthickfactor)
        self.eyewidth = SV(self.height * self.eyewidthfactor)

        self.avgheightcomp = SV(defaultheight * self.viewscale)
        self.avgweightcomp = WV(defaultweight * self.viewscale**3)

        viewangle = calcViewAngle(self.height, defaultheight)
        self.avglookangle = abs(viewangle)
        self.avglookdirection = "up" if viewangle >= 0 else "down"

        defaultwalkspeed = SV.parse("2.5mi")
        defaultrunspeed = SV.parse("7.5mi")

        self.walkperhour = SV(defaultwalkspeed * self.averageheightmult)
        self.runperhour = SV(defaultrunspeed * self.averageheightmult)
Example #5
0
def WV_format():
    value = Decimal(request.args.get("value"))
    system = request.args.get("system")
    try:
        val = WV(value)
    except InvalidSizeValue:
        abort(404)
    return json.dumps({"formatted": format(val, system)})
Example #6
0
    def addToUnits(self):
        if self.unitlength is not None:
            SV.addUnit(
                Unit(factor=self.unitlength,
                     name=self.name,
                     namePlural=self.namePlural,
                     names=self.aliases,
                     symbol=self.symbol))
            SV.addSystemUnit("o", SystemUnit(self.name))

        if self.weight is not None:
            WV.addUnit(
                Unit(factor=self.weight,
                     name=self.name,
                     namePlural=self.namePlural,
                     names=self.aliases,
                     symbol=self.symbol))
            WV.addSystemUnit("o", SystemUnit(self.name))
Example #7
0
    async def setbaseweight(self, ctx, *, newbaseweight: WV):
        """Change base weight."""
        userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True)

        if "setweight" in userdata.registration_steps_remaining:
            if not (WV.parse("10lb") < newbaseweight < WV.parse("1000lb")):
                await ctx.send(
                    f"{emojis.warning} **WARNING:** Your base weight should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base weight similar to that of a normal human being."
                )

        userdata.baseweight = newbaseweight
        completed_registration = userdata.complete_step("setweight")
        userdb.save(userdata)

        await ctx.send(
            f"{userdata.nickname}'s base weight is now {userdata.baseweight:mu}"
        )

        await proportions.nickUpdate(ctx.author)
        await showNextStep(ctx, userdata, completed=completed_registration)
Example #8
0
    async def setbaseweight(self, ctx, *, newbaseweight):
        """Change base weight."""
        userdata = userdb.load(ctx.guild.id, ctx.author.id)

        userdata.baseweight = WV.parse(newbaseweight)
        userdb.save(userdata)

        logger.info(
            f"User {ctx.author.id} ({ctx.author.display_name}) changed their base weight to {newbaseweight}."
        )
        await ctx.send(
            f"<@{ctx.author.id}>'s base weight is now {userdata.baseweight:mu}"
        )

        await proportions.nickUpdate(ctx.author)
Example #9
0
    async def setbase(self,
                      ctx,
                      arg1: typing.Union[SV, WV],
                      arg2: typing.Union[SV, WV] = None):
        """Set your base height and weight."""
        userdata = userdb.load(ctx.guild.id, ctx.author.id, allow_unreg=True)

        # Don't allow a user to enter setbase(SV, SV) or setbase(WV, WV)
        if (isinstance(arg1, SV)
                and isinstance(arg2, SV)) or (isinstance(arg1, WV)
                                              and isinstance(arg2, WV)):
            raise errors.UserMessedUpException(
                "Please do not enter two heights or two weights.")

        newbaseheight = None
        newbaseweight = None
        for arg in [arg1, arg2]:
            if isinstance(arg, SV):
                newbaseheight = arg
            if isinstance(arg, WV):
                newbaseweight = arg
        completed_registration = False
        if newbaseheight is not None:
            if "setheight" in userdata.registration_steps_remaining:
                userdata.height = newbaseheight
                if not (SV.parse("4ft") < newbaseheight < SV.parse("8ft")):
                    await ctx.send(
                        f"{emojis.warning} **WARNING:** Your base height should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base height similar to the size of a normal human being."
                    )
            userdata.baseheight = newbaseheight
            completed_registration = userdata.complete_step(
                "setheight") or completed_registration
        if newbaseweight is not None:
            if "setweight" in userdata.registration_steps_remaining:
                if not (WV.parse("10lb") < newbaseheight < SV.parse("1000lb")):
                    await ctx.send(
                        f"{emojis.warning} **WARNING:** Your base weight should probably be something more human-scale. This makes comparison math work out much nicer. If this was intended, you can ignore this warning, but it is ***highly recommended*** that you have a base weight similar to that of a normal human being."
                    )
            userdata.baseweight = newbaseweight
            completed_registration = userdata.complete_step(
                "setweight") or completed_registration
        userdb.save(userdata)

        await ctx.send(
            f"{userdata.nickname} changed their base height and weight to {userdata.baseheight:,.3mu} and {userdata.baseweight:,.3mu}"
        )
        await showNextStep(ctx, userdata, completed=completed_registration)
Example #10
0
    def __init__(self,
                 name,
                 dimension,
                 aliases=[],
                 symbol=None,
                 height=None,
                 length=None,
                 width=None,
                 diameter=None,
                 depth=None,
                 thickness=None,
                 weight=None):

        self.name = name
        self.namePlural = getPlural(name)
        self.singularNames = aliases + [self.name]
        self.aliases = aliases + [getPlural(a) for a in aliases]
        self.article = getIndefiniteArticle(self.name).split(" ")[0]
        self.symbol = symbol or None

        self.height = height and SV(height)
        self.length = length and SV(length)
        self.width = width and SV(width)
        self.diameter = diameter and SV(diameter)
        self.depth = depth and SV(depth)
        self.thickness = thickness and SV(thickness)
        self.weight = weight and WV(weight)

        dimensionmap = {
            "h": "height",
            "l": "length",
            "w": "width",
            "d": "diameter",
            "p": "depth",
            "t": "thickness"
        }

        self.unitlength = getattr(self, dimensionmap[dimension])
Example #11
0
import json
from copy import copy
from functools import total_ordering
from typing import Literal

from sizebot import conf
from sizebot.lib import errors
from sizebot.lib.units import SV, WV

# Defaults
defaultheight = SV("1.754")  # meters
defaultweight = WV("66760")  # grams

# Map the deprecated user array constants to the new names
# TODO: This is used never, I think?
#                      NICK        DISP       CHEI      BHEI          BWEI          UNIT          SPEC
DEPRECATED_NAME_MAP = [
    "nickname", "display", "height", "baseheight", "baseweight", "unitsystem",
    "species"
]


@total_ordering
class User:
    # __slots__ declares to python what attributes to expect.
    __slots__ = [
        "guildid", "id", "nickname", "_gender", "display", "_height",
        "_baseheight", "_baseweight", "_footlength", "_hairlength",
        "_taillength", "_unitsystem", "species"
    ]
Example #12
0
 def weight(self):
     return WV(self.baseweight * (self.scale**3))
Example #13
0
 def baseweight(self, value):
     value = WV(value)
     if value < 0:
         value = WV(0)
     self._baseweight = value
Example #14
0
from functools import total_ordering
import importlib.resources as pkg_resources
from typing import Literal

import arrow

import sizebot.data
from sizebot.lib import errors, paths
from sizebot.lib.decimal import Decimal
from sizebot.lib.diff import Diff, Rate as ParseableRate
from sizebot.lib.units import SV, WV
from sizebot.lib.utils import isURL, truncate

# Defaults
defaultheight = SV("1.754")  # meters
defaultweight = WV("66760")  # grams
defaultterminalvelocity = SV("63.63")  # meters/second
falllimit = SV("7.73")  # meters/second
defaultliftstrength = WV("18143.7")  # grams

modelJSON = json.loads(pkg_resources.read_text(sizebot.data, "models.json"))


@total_ordering
class User:
    # __slots__ declares to python what attributes to expect.
    __slots__ = [
        "guildid", "id", "nickname", "lastactive", "_picture_url",
        "description", "_gender", "display", "_height", "_baseheight",
        "_baseweight", "_footlength", "_pawtoggle", "_furtoggle",
        "_hairlength", "_taillength", "_earheight", "_liftstrength",
Example #15
0
    def __init__(self, userdata):
        self.nickname = userdata.nickname
        self.tag = userdata.tag
        self.gender = userdata.autogender
        self.height = userdata.height
        self.baseheight = userdata.baseheight
        self.viewscale = userdata.viewscale
        self.scale = userdata.scale
        self.formattedscale = userdata.getFormattedScale(verbose=True)
        self.baseweight = userdata.baseweight
        self.weight = userdata.weight
        self.formattedweightscale = userdata.getFormattedScale(
            scaletype="weight", verbose=True)
        self.footname = userdata.footname
        self.hairname = userdata.hairname
        self.pawtoggle = userdata.pawtoggle
        self.furtoggle = userdata.furtoggle
        self.macrovision_model = userdata.macrovision_model
        self.macrovision_view = userdata.macrovision_view

        self.averageheightmult = self.height / defaultheight
        self.averageweightmult = self.weight / defaultweight

        if userdata.hairlength is None:
            self.hairlength = None
        else:
            self.hairlength = SV(userdata.hairlength / self.viewscale)

        if userdata.taillength is None:
            self.taillength = None
        else:
            self.taillength = SV(userdata.taillength / self.viewscale)

        if userdata.earheight is None:
            self.earheight = None
        else:
            self.earheight = SV(userdata.earheight / self.viewscale)

        if userdata.liftstrength is None:
            self.liftstrength = WV(defaultliftstrength / (self.viewscale**3))
        else:
            self.liftstrength = WV(userdata.liftstrength / (self.viewscale**3))

        if userdata.footlength is None:
            self.footlength = SV(self.height * self.footfactor)
        else:
            self.footlength = SV(userdata.footlength / self.viewscale)
        self.shoesize = formatShoeSize(self.footlength, self.gender == "f")
        self.footwidth = SV(self.height * self.footwidthfactor)
        self.toeheight = SV(self.height * self.toeheightfactor)
        self.shoeprintdepth = SV(self.height * self.toeheightfactor)
        self.pointerlength = SV(self.height * self.pointerfactor)
        self.thumbwidth = SV(self.height * self.thumbfactor)
        self.fingerprintdepth = SV(self.height * self.fingerprintfactor)

        self.threadthickness = SV(self.defaultthreadthickness *
                                  self.averageheightmult)

        self.hairwidth = SV(
            (self.baseheight * self.hairfactor) / self.viewscale)
        self.nailthickness = SV(
            (self.baseheight * self.nailthickfactor) / self.viewscale)
        self.eyewidth = SV(self.height * self.eyewidthfactor)

        self.avgheightcomp = SV(defaultheight * self.viewscale)
        self.avgweightcomp = WV(defaultweight * self.viewscale**3)

        viewangle = calcViewAngle(self.height, defaultheight)
        self.avglookangle = abs(viewangle)
        self.avglookdirection = "up" if viewangle >= 0 else "down"

        if userdata.walkperhour is None:
            self.walkperhour = SV(self.defaultwalkspeed *
                                  self.averageheightmult)
        else:
            self.walkperhour = SV(userdata.walkperhour *
                                  self.averageheightmult)

        if userdata.runperhour is None:
            self.runperhour = SV(self.defaultrunspeed * self.averageheightmult)
        else:
            self.runperhour = SV(userdata.runperhour * self.averageheightmult)

        self.walksteplength = SV(self.walkperhour / self.walkstepsperhour)
        self.runsteplength = SV(self.runperhour / self.runstepsperhour)

        self.horizondistance = SV(
            math.sqrt(math.pow(self.height + 6378137, 2) - 40680631590769))

        self.terminalvelocity = SV(defaultterminalvelocity *
                                   Decimal(math.sqrt(self.scale)))
        self.fallproof = self.terminalvelocity < falllimit
        self.fallproofcheck = emojis.voteyes if self.fallproof else emojis.voteno
Example #16
0
 def baseweight(self, value):
     self._baseweight = WV(max(0, WV(value)))
def test_negative_WV_parse():
    result = WV.parse("-12kg")
    assert result == WV("-12000")
Example #18
0
    async def lookat(self, ctx, *, what: typing.Union[DigiObject, discord.Member, SV, str]):
        """See what an object looks like to you.

        Used to see how an object would look at your scale.
        Examples:
        `&lookat man`
        `&look book`
        `&examine building`"""

        if isinstance(what, SV):
            telemetry.SizeViewed(what).save()

        userdata = getUserdata(ctx.author)

        if isinstance(what, str):
            what = what.lower()

        if isinstance(what, DigiObject):
            telemetry.ObjectUsed(str(what)).save()
            la = what.relativestatssentence(userdata)
            # Easter eggs.
            if what.name == "photograph":
                la += "\n\n<https://www.youtube.com/watch?v=BB0DU4DoPP4>"
                logger.log(EGG, f"{ctx.author.display_name} is jamming to Nickleback.")
            if what.name == "enderman":
                la += f"\n\n`{ctx.author.display_name} was slain by an Enderman.`"
                logger.log(EGG, f"{ctx.author.display_name} was slain by an Enderman.")
            await ctx.send(la)
            return
        elif isinstance(what, discord.Member) or isinstance(what, SV):  # TODO: Make this not literally just a compare. (make a sentence)
            compdata = getUserdata(what)
        elif isinstance(what, str) and what.lower() in ["person", "man", "average", "average person", "average man", "average human", "human"]:
            compheight = userdb.defaultheight
            compdata = getUserdata(compheight, nickname = "an average person")
        elif isinstance(what, str) and what.lower() in ["chocolate", "stuffed animal", "stuffed beaver", "beaver"]:
            logger.log(EGG, f"{ctx.author.display_name} found Chocolate!")
            compdata = getUserdata(SV.parse("11in"), nickname = "Chocolate [Stuffed Beaver]")
            compdata.baseweight = WV.parse("4.8oz")
            compdata.footlength = SV.parse("2.75in")
            compdata.taillength = SV.parse("12cm")
        elif isinstance(what, str) and what.lower() in ["me", "myself"]:
            compdata = userdb.load(ctx.guild.id, ctx.author.id)
        else:
            # Easter eggs.
            if what.lower() in ["all those chickens", "chickens"]:
                await ctx.send("https://www.youtube.com/watch?v=NsLKQTh-Bqo")
                logger.log(EGG, f"{ctx.author.display_name} looked at all those chickens.")
                return
            if what.lower() == "that horse":
                await ctx.send("https://www.youtube.com/watch?v=Uz4bW2yOLXA")
                logger.log(EGG, f"{ctx.author.display_name} looked at that horse (it may in fact be a moth.)")
                return
            if what.lower() == "my horse":
                await ctx.send("https://www.youtube.com/watch?v=o7cCJqya7wc")
                logger.log(EGG, f"{ctx.author.display_name} looked at my horse (my horse is amazing.)")
                return
            if what.lower() == "cake":
                await ctx.send("The cake is a lie.")
                logger.log(EGG, f"{ctx.author.display_name} realized the cake was lie.")
                return
            if what.lower() == "snout":
                await ctx.send("https://www.youtube.com/watch?v=k2mFvwDTTt0")
                logger.log(EGG, f"{ctx.author.display_name} took a closer look at that snout.")
                return
            await ctx.send(
                f"Sorry, I don't know what `{what}` is.\n"
                f"If this is an object or alias you'd like added to SizeBot, "
                f"use `{ctx.prefix}suggestobject` to suggest it "
                f"(see `{ctx.prefix}help suggestobject` for instructions on doing that.)"
            )
            telemetry.UnknownObject(str(what)).save()
            return
        stats = proportions.PersonComparison(userdata, compdata)
        embedtosend = await stats.toEmbed(requesterID = ctx.message.author.id)
        await ctx.send(embed = embedtosend)