From bccc56fc450773e534c88c2b875da54aec804241 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 12 Apr 2023 16:50:15 +1000 Subject: [PATCH 1/3] First refactor --- SettingsTemplate.yaml | 13 +++ listfile.txt | 9 -- main.py | 4 +- plugin/__init__.py | 25 ---- plugin/extensions.py | 10 -- plugin/general_converter.py | 219 ++++++++++++++++++++++++++++++++++++ plugin/settings.py | 41 ------- plugin/templates.py | 18 --- plugin/translation.py | 24 ++++ plugin/ui.py | 111 ------------------ plugin/units.py | 2 +- test.py | 8 -- 12 files changed, 259 insertions(+), 225 deletions(-) create mode 100644 SettingsTemplate.yaml delete mode 100644 listfile.txt delete mode 100644 plugin/__init__.py delete mode 100644 plugin/extensions.py create mode 100644 plugin/general_converter.py delete mode 100644 plugin/settings.py delete mode 100644 plugin/templates.py create mode 100644 plugin/translation.py delete mode 100644 plugin/ui.py delete mode 100644 test.py diff --git a/SettingsTemplate.yaml b/SettingsTemplate.yaml new file mode 100644 index 0000000..73e3b89 --- /dev/null +++ b/SettingsTemplate.yaml @@ -0,0 +1,13 @@ +body: + - type: textBlock + attributes: + name: description + description: > + Convert between different types of units. + - type: checkbox + attributes: + attributes: + name: show_helper_text + label: "Show helper text of what can be converted" + defaultValue: "true" + description: "If you remove the keyword for this plugin so it triggers on any number then turn this off" diff --git a/listfile.txt b/listfile.txt deleted file mode 100644 index 7d3ae8f..0000000 --- a/listfile.txt +++ /dev/null @@ -1,9 +0,0 @@ -.env -main.py -plugin.json -README.MD -requirements.txt -assets\ -plugin\*.py -plugin\translations\en -plugin\translations\zh diff --git a/main.py b/main.py index e1f2066..060ffc0 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,7 @@ sys.path.append(os.path.join(parent_folder_path, "lib")) sys.path.append(os.path.join(parent_folder_path, "plugin")) -from plugin import Main +from plugin.general_converter import GenConvert if __name__ == "__main__": - Main() \ No newline at end of file + GenConvert() diff --git a/plugin/__init__.py b/plugin/__init__.py deleted file mode 100644 index 66b0551..0000000 --- a/plugin/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Currency Converter -===== -Uses the European Central Bank to convert currencies. -""" - - -from plugin.settings import ( - GITHUB_USERNAME, - ICON_PATH, - PLUGIN_ACTION_KEYWORD, - PLUGIN_AUTHOR, - PLUGIN_EXECUTE_FILENAME, - PLUGIN_ID, - PLUGIN_PROGRAM_LANG, - PLUGIN_URL, - __long_description__, - __package_name__, - __package_title__, - __short_description__, - __version__, - basedir, -) -from plugin.ui import Main \ No newline at end of file diff --git a/plugin/extensions.py b/plugin/extensions.py deleted file mode 100644 index 5d07e27..0000000 --- a/plugin/extensions.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -import gettext - -from plugin.settings import LOCAL - -# localization -translation = gettext.translation("messages", "plugin/translations/", languages=[LOCAL]) - -_ = translation.gettext \ No newline at end of file diff --git a/plugin/general_converter.py b/plugin/general_converter.py new file mode 100644 index 0000000..ca92f0b --- /dev/null +++ b/plugin/general_converter.py @@ -0,0 +1,219 @@ +import locale +import decimal +import textwrap +import re +import units as gc_units + +from translation import _ +from flox import Flox + + +class GenConvert(Flox): + locale.setlocale(locale.LC_NUMERIC, "") + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.logger_level("info") + + def query(self, query): + q = query.strip() + args = q.split(" ") + # Just keyword - show all units if the setting allows + if len(args) == 1: + all_units = get_all_units() + self.add_item( + title=_("General Converter"), + subtitle=_(" "), + ) + if not self.settings.get("show_helper_text"): + for cat in all_units: + title = str(cat[0]) + subtitle = ", ".join([str(elem) for elem in cat[1:]]) + lines = textwrap.wrap(subtitle, 110, break_long_words=False) + if len(lines) > 1: + self.add_item( + title=(title), + subtitle=(lines[0]), + icon=f"assets/{title}.ico", + ) + for line in range(1, len(lines)): + self.add_item( + title=(title), + subtitle=(lines[line]), + icon=f"assets/{title}.ico", + ) + else: + self.add_item( + title=(title), + subtitle=(subtitle), + icon=f"assets/{title}.ico", + ) + # Keyword and first unit to convert from - show what it can be converted to + elif len(args) == 2: + hints = get_hints_for_category(args[1].lower()) + self.add_item( + title=_("Available conversions"), + subtitle=(f"{args[0]} {args[1]} to {', '.join(hints)}"), + ) + # Keyword and two units to convert from and to - try to convert + elif len(args) == 3: + try: + # Units are currently case insensitive. May need to change this if in future new units + # with official upper case shorthand are catered for + args[1] = args[1].lower() + args[2] = args[2].lower() + do_convert = gen_convert(float(args[0]), args[1], args[2]) + if "Error" in do_convert: + if do_convert["Error"] == _("To and from unit is the same"): + self.add_item( + title=_("{}".format(do_convert["Error"])), + subtitle=_("Choose two different units"), + ) + else: + self.add_item( + # f strings seem to break babel so use string formatting instead + title=_("Error - {}").format(do_convert["Error"]), + subtitle=_("Check documentation for accepted units"), + ) + else: + c = do_convert["converted"] + p = smart_precision(locale.localeconv()["decimal_point"], c, 3) + self.add_item( + title=(do_convert["category"]), + subtitle=( + f"{locale.format_string('%.10g', float(args[0]), grouping=True)} {args[1]} = {locale.format_string(f'%.{p}f', c, grouping=True)} {args[2]}" + ), + icon=f"assets/{do_convert['category']}.ico", + ) + do_convert = [] + except Exception as e: + self.add_item(title="Error - {}").format(repr(e), subtitle="") + # Always show the usage while there isn't a valid query + else: + self.add_item( + title=_("General Converter"), + subtitle=_(" "), + ) + + +def get_all_units(short=False): + """Returns all available units as a list of lists by category + + :param short: if True only unit abbreviations are returned, default is False + :type amount: bool + + :rtype: list of lists + :return: A list of lists for each category in units. Index 0 of each internal list + is the category description + """ + + full_list = [] + for u in gc_units.units: + cat_list = [] + cat_list.append(u) + for u2 in gc_units.units[u]: + cat_list.append(u2[0] if short else f"{u2[1]} ({u2[0]})") + full_list.append(cat_list) + return full_list + + +def get_hints_for_category(from_unit: str): + """Takes an input unit and returns a list of units it can be converted to + + :param from_short: unit abbreviation + :type amount: str + + :rtype: list + :return: A list of other unit abbreviations in the same category + """ + c = [] + category = "" + + # Find the category it's in + for u in gc_units.units: + for u2 in gc_units.units[u]: + if u2[0] == from_unit: + category = str(u) + for uu in gc_units.units[category]: + if uu[0] != from_unit: + c.append(uu[0]) + if category: + return c + else: + return ["no valid units"] + + +def gen_convert(amount: float, from_unit: str, to_unit: str): + """Converts from one unit to another + + :param amount: amount of source unit to convert + :type amount: float + :param from_unit: abbreviation of unit to convert from + :type from_unit: str + :param to_unit: abbreviation of unit to convert to + :type to_unit: str + + :rtype: dict + :return: if to_unit and from_unit are valid returns a dictionary + { + "category":{category of units}, + "converted":{converted amount}, + "fromabbrev":{from unit abbreviation}, + "fromlong":{from unit long name}, + "fromplural":{from unit plural name}, + "toabbrev":{to unit abbreviation}, + "tolong":{to unit long name}, + "toplural":{to unit plural name}, + } + + else returns a dictionary with error status + {"Error": {error text}} + """ + conversions = {} + found_from = found_to = [] + if from_unit == to_unit: + conversions["Error"] = _("To and from unit is the same") + return conversions + for u in gc_units.units: + for u2 in gc_units.units[u]: + if u2[0] == from_unit: + found_from = u2 + if u2[0] == to_unit: + found_to = u2 + # If we haven't both in the same category, reset + if found_to and found_from: + found_category = u + break + else: + found_from = found_to = [] + if found_to and found_from: + base_unit_conversion = eval(found_from[3].replace("x", str(amount))) + final_conversion = eval(found_to[4].replace("x", str(base_unit_conversion))) + conversions["category"] = found_category + conversions["converted"] = final_conversion + conversions["fromabbrev"] = found_from[0] + conversions["fromlong"] = found_from[1] + conversions["fromplural"] = found_from[2] + conversions["toabbrev"] = found_to[0] + conversions["tolong"] = found_to[1] + conversions["toplural"] = found_to[2] + + else: + conversions["Error"] = "Problem converting {} and {}".format(from_unit, to_unit) + return conversions + + +def smart_precision(separator, amount, preferred=3): + str_amt = str(amount) + dec_places = str_amt[::-1].find(separator) + # whole number + if dec_places == -1: + return 0 + frac_part = str_amt[-dec_places::] + # fraction is just zeroes + if int(frac_part) == 0: + return 0 + fnz = re.search(r"[1-9]", frac_part).start() + if fnz < preferred: + return preferred + return fnz + 1 diff --git a/plugin/settings.py b/plugin/settings.py deleted file mode 100644 index 690e87b..0000000 --- a/plugin/settings.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -from dotenv import load_dotenv - -basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - -dotenv_path = os.path.join(basedir, ".env") -if os.path.exists(dotenv_path): - load_dotenv(dotenv_path) - - -# The default value can work, if no user config. -LOCAL = os.getenv("local", "en") - - -ICON_PATH = "assets/favicon.ico" - -# the information of package -__package_name__ = "Flow.Launcher.Plugin.GenConvert" -__package_title__ = "General Converter" -__version__ = "1.0.0" -__short_description__ = "General weights and measures converter" -GITHUB_USERNAME = "deefrawley" - - -readme_path = os.path.join(basedir, "README.md") -try: - __long_description__ = open(readme_path, "r").read() -except: - __long_description__ = __short_description__ - - -# other information -PLUGIN_ID = "73f2c04d-176a-4586-9ff5-69fae63321ef" -ICON_PATH = "assets/favicon.ico" -PLUGIN_ACTION_KEYWORD = "gc" -PLUGIN_AUTHOR = "deefrawley" -PLUGIN_PROGRAM_LANG = "python" -PLUGIN_URL = f"https://github.com/{GITHUB_USERNAME}/{__package_name__}" -PLUGIN_EXECUTE_FILENAME = "main.py" diff --git a/plugin/templates.py b/plugin/templates.py deleted file mode 100644 index 670cf02..0000000 --- a/plugin/templates.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - - -from plugin.settings import ICON_PATH - - -RESULT_TEMPLATE = { - "Title": "", - "SubTitle": "", - "IcoPath": ICON_PATH, -} - -ACTION_TEMPLATE = { - "JsonRPCAction": { - "method": "", - "parameters": [], - } -} \ No newline at end of file diff --git a/plugin/translation.py b/plugin/translation.py new file mode 100644 index 0000000..01c8412 --- /dev/null +++ b/plugin/translation.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +import os +import gettext +from dotenv import load_dotenv + +# TODO - Move language option to Flow setting and remove need for dotenv + +LOCAL = os.getenv("local", "en") + +basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + +dotenv_path = os.path.join(basedir, ".env") +if os.path.exists(dotenv_path): + load_dotenv(dotenv_path) + +# localization +translation = gettext.translation( + "messages", + os.path.join(basedir, "plugin/translations"), + languages=[LOCAL], +) +translation.install() + +_ = translation.gettext diff --git a/plugin/ui.py b/plugin/ui.py deleted file mode 100644 index 287e05d..0000000 --- a/plugin/ui.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- -import textwrap -import copy -import locale -import plugin.utils - -from typing import List -from plugin.templates import RESULT_TEMPLATE, ACTION_TEMPLATE -from flowlauncher import FlowLauncher -from plugin.extensions import _ - - -class Main(FlowLauncher): - messages_queue = [] - locale.setlocale(locale.LC_NUMERIC, "") - - def sendNormalMess( - self, title: str, subtitle: str, iconpath: str = "assets/favicon.ico" - ): - message = copy.deepcopy(RESULT_TEMPLATE) - message["Title"] = title - message["SubTitle"] = subtitle - message["IcoPath"] = iconpath - - self.messages_queue.append(message) - - def sendActionMess(self, title: str, subtitle: str, method: str, value: List): - # information - message = copy.deepcopy(RESULT_TEMPLATE) - message["Title"] = title - message["SubTitle"] = subtitle - - # action - action = copy.deepcopy(ACTION_TEMPLATE) - action["JsonRPCAction"]["method"] = method - action["JsonRPCAction"]["parameters"] = value - message.update(action) - - self.messages_queue.append(message) - - def query(self, param: str) -> List[dict]: - q = param.strip() - args = q.split(" ") - # Just keyword - show all units - if len(args) == 1: - all_units = plugin.utils.get_all_units() - self.sendNormalMess( - (_("General Converter")), - _(" "), - ) - for cat in all_units: - title = str(cat[0]) - subtitle = ", ".join([str(elem) for elem in cat[1:]]) - lines = textwrap.wrap(subtitle, 110, break_long_words=False) - if len(lines) > 1: - self.sendNormalMess((title), (lines[0]), f"assets/{title}.ico") - for line in range(1, len(lines)): - self.sendNormalMess( - (title), (lines[line]), f"assets/{title}.ico" - ) - else: - self.sendNormalMess((title), (subtitle), f"assets/{title}.ico") - # Keyword and first unit to convert from - show what it can be converted to - elif len(args) == 2: - hints = plugin.utils.get_hints_for_category(args[1].lower()) - self.sendNormalMess( - _("Available conversions"), - (f"{args[0]} {args[1]} to {', '.join(hints)}"), - ) - # Keyword and two units to convert from and to - try to convert - elif len(args) == 3: - try: - # Units are currently case insensitive. May need to change this if in future new units - # with official upper case shorthand are catered for - args[1] = args[1].lower() - args[2] = args[2].lower() - do_convert = plugin.utils.gen_convert(float(args[0]), args[1], args[2]) - if "Error" in do_convert: - if do_convert["Error"] == "To and from unit is the same": - self.sendNormalMess( - _("{}".format(do_convert["Error"])), - _("Choose two different units"), - ) - else: - self.sendNormalMess( - # f strings seem to break babel so use string formatting instead - _("Error - {}").format(do_convert["Error"]), - _("Check documentation for accepted units"), - ) - else: - c = do_convert["converted"] - p = plugin.utils.smart_precision( - locale.localeconv()["decimal_point"], c, 3 - ) - self.sendNormalMess( - (do_convert["category"]), - ( - f"{locale.format_string('%.10g', float(args[0]), grouping=True)} {args[1]} = {locale.format_string(f'%.{p}f', c, grouping=True)} {args[2]}" - ), - f"assets/{do_convert['category']}.ico", - ) - do_convert = [] - except Exception as e: - self.sendNormalMess(_("Error - {}").format(repr(e)), "") - # Always show the usage while there isn't a valid query - else: - self.sendNormalMess( - _("General Converter"), - _(" "), - ) - return self.messages_queue diff --git a/plugin/units.py b/plugin/units.py index fe222c5..326a6a7 100644 --- a/plugin/units.py +++ b/plugin/units.py @@ -1,4 +1,4 @@ -from plugin.extensions import _ +from translation import _ """ Unit Syntax: diff --git a/test.py b/test.py deleted file mode 100644 index 5d8de95..0000000 --- a/test.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - - -from plugin import Main - -if __name__ == "__main__": - r = Main().query("") - print(r) \ No newline at end of file From abfb3a3b4c2c33b1589e62f3c1cb625b96cb5ef9 Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 12 Apr 2023 19:48:05 +1000 Subject: [PATCH 2/3] Add long form abb, new units, setting to turn off helper text --- LICENSE | 14 ++-- README.md | 117 +++++++++++++++++++++++++++++-- SettingsTemplate.yaml | 1 - assets/Energy.ico | Bin 0 -> 11902 bytes assets/Energy.png | Bin 0 -> 18754 bytes assets/Speed.ico | Bin 0 -> 11390 bytes plugin.json | 2 +- plugin/general_converter.py | 20 +++--- plugin/units.py | 136 ++++++++++++++++++++++++++++++++++++ plugin/utils.py | 128 --------------------------------- requirements-dev.txt | 2 - requirements.txt | 5 +- 12 files changed, 266 insertions(+), 159 deletions(-) create mode 100644 assets/Energy.ico create mode 100644 assets/Energy.png create mode 100644 assets/Speed.ico delete mode 100644 plugin/utils.py delete mode 100644 requirements-dev.txt diff --git a/LICENSE b/LICENSE index 483ea73..a506857 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 deefrawley +Copyright (c) 2023 deefrawley Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -20,8 +20,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Graduated Cylinder icon by AS Design from the Noun Project -area icon by matteo manenti from the Noun Project -distance icon by Anthony Ledoux from the Noun Project -Weight icon by Adrien Coquet from the Noun Project -Temperature icon by Alexander Skowalsky from the Noun Project +Graduated Cylinder icon by AS Design from Noun Project +Area icon by matteo manenti from Noun Project +Distance icon by Anthony Ledoux from Noun Project +Weight icon by Adrien Coquet from Noun Project +Temperature icon by Alexander Skowalsky from Noun Project +Speed icon by Fahmi Somdi Std from Noun Project +Energy icon by Greg Cresnar from Noun Project diff --git a/README.md b/README.md index b67d681..749b2ce 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) # General Converter (Flow.Launcher.GenConvert) -General weight, volume, distance, area, temperature converter for the [Flow Launcher](https://github.com/Flow-Launcher/Flow.Launcher) +General weight, volume, distance, area, temperature, speed and energy converter for the [Flow Launcher](https://github.com/Flow-Launcher/Flow.Launcher) ### About ### Requirements -Python 3.5 or later. As of Flow Launcher v1.8, Flow should take care of the installation of Python for you if it is not on your system. +Python 3.9 or later. As of Flow Launcher v1.8, Flow should take care of the installation of Python for you if it is not on your system. ### Installing @@ -29,7 +29,10 @@ Currently English and Chinese language supported. Edit the .env file to change t | ------------------------------------------------------------- | -------------------------------------------------- | | `gc ` | Convert the amount of the from unit to the to unit. | -Just entering the keyword will give you the full list of units to choose from in Flow. +The from and to unit are case sensitive. + +Just entering the keyword will give you the full list of units to choose from in Flow. If you want to remove the keyword for this plugin and have it return +results when you simply start entering a number then go to the Plugin settings and turn this helper text off. Entering the keyword, amount and from unit will give you a subset list of units the from unit can be converted to #### Units @@ -41,10 +44,10 @@ The following units and their abbreviations can be used (each table can only con Subject Unit Abbreviation - Distance Logo + Distance Logo - Distance + Distance millimetre mm @@ -56,6 +59,10 @@ The following units and their abbreviations can be used (each table can only con metre m + + decimetre + dm + kilometre km @@ -83,10 +90,10 @@ The following units and their abbreviations can be used (each table can only con Subject Unit Abbreviation - Volume Logo + Volume Logo - Volume + Volume millilitre ml @@ -98,6 +105,10 @@ The following units and their abbreviations can be used (each table can only con litre l + + decalitre + decal + pint US pt @@ -154,6 +165,38 @@ The following units and their abbreviations can be used (each table can only con fluid ounce Imperial flozimp + + cubic decimetre + dm3 + + + cubic millimetre + mm3 + + + cubic centimetre + cm3 + + + cubic metre + m3 + + + cubic inch + in3 + + + cubic feet + ft3 + + + bushel UK + buuk + + + bushel US + buus + @@ -258,6 +301,66 @@ The following units and their abbreviations can be used (each table can only con
+ + + + + + + + + + + + + + + + + + + + +
SubjectUnitAbbreviationSpeed Logo
Speedkilometres per hourkm/h
miles per hourmp/h
knotskt
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SubjectUnitAbbreviationEnergy Logo
Energycaloriescal
kilocalorieskcal
kilojouleskJ
megajoulesMJ
gigajoulesGj
kilowatt hourskWh
British thermal unitsBTU
+ ### Problems, errors and feature requests Open an issue in this repo. diff --git a/SettingsTemplate.yaml b/SettingsTemplate.yaml index 73e3b89..7c05998 100644 --- a/SettingsTemplate.yaml +++ b/SettingsTemplate.yaml @@ -6,7 +6,6 @@ body: Convert between different types of units. - type: checkbox attributes: - attributes: name: show_helper_text label: "Show helper text of what can be converted" defaultValue: "true" diff --git a/assets/Energy.ico b/assets/Energy.ico new file mode 100644 index 0000000000000000000000000000000000000000..139a6d0c9703f273f0a9789973fcb3253e416dc6 GIT binary patch literal 11902 zcmeI2J&qek5QTe80}Pi;?2xG=Ux8>eF^a>Jc1JehGB@VzwWN; zuIlMotrZv^L0t0nn^#}e^vr4(N@;;VAJ!ARew*I?n9_GCr61t$2lxvj>G;+=eogN^ zd0IQa$&u2V#GL=n8P9QZJ|{ZHA+S2mQJZI3hFPPWlZwH&qoBcRlL8+HNMTM3!>J)s zl+(ko5+MaSJ`F|%ME*iVgSt=T=EO7@s{@z-6qN2l` z+E~enYVOU6c(7!+wu6VP5p2E1a$n<;;VO1b#~0?5#@;$7oB)p?T+WTn@x)iGoljVh zc{T?vJfSb|{isgU*H_C43)%e>VS_H@k;CSM<=}L7Mh=@3RYRSfk)z;}Evi;?BF8*W zspuk=)k&UcOKPF6FF^T-Vp2U7tT3bGLFB4w&zo>X$kUxCiP zkN<1|8`r}I{G;J{b&iZDKcB-K9+1z1YReOjU}HejJXA2|X>&pzYHYlUS!yE%McEZB z=J8DApf%*dB6Mu?40C#(up|yBTof8LpU_HMWNSQiKEs@7v9wil;9Yb8e6Zx@L^bJ3 z1UY3qiYLy2s(wzznaY7H<`;2uf|^LOizlebIX+JvkLoKb3PHgyw^UnmImu^LIFmX4 zZ^@#Zc+xJ9Zp-k*IXLX@h;#g_(gld1+p;{nfDBHPvj@oFG&wtfEKZv<4`gxLoN1s2 zr^}fIYH+%oNuU;|&zS>iar&Gopbp2$aqlI&r#l*a=5*p_XFZLZvkBBy2EpMOJQ%4x z5690L5_vQM&xpvS33EaspC-*`ycpEGxfJXg4%uA%IQuBg#T{NvpxPusg<7pp7#0ok5aAHfPX37SS;F~unAup z?GD;vwa>IyuO#Mk;VT?RqdiDF7>%TqZYavR9GB8nX&fhk;^R0W6zwi~L@3%S8V#7W zT!IU?8Wv^^2fzo8fi-yTw0o8kcE>(XTZ<22*jJ^ZRXhSDpVqE&?%#OskpnKG5%O^* z5uoW@cqu-(B&0o1JFNJMmx;7HemKx8HllnFTq)X}K0NRh_X7D={BVG`c!);t7e_nD zV2zKu!GJ?V|| z!MZ$sUO>yyi2d>6hPqR}|gMfNH4vGyXG-WyqCU*0=Nj5jOtSxxW1gY0|u(b#}t zrE|4!5g%*pOU5S+nEOby8|Rt(O*Fo@q^Ya+iFUaY%Z>WT8v9twVA_|#SbNgBq8&*y z&!Kd9Bsj8026?b$jSS+;&pICJLQDCX$XX)JJWo^lCBcz384UR@!Y3Nq;4#F^(lBXP z(WGJ0ZdqIDBfUJcb}t%kYe0k7N6~QmvnJ56BDWK)$Q1?+Z#(u?z)R68;I(KK@K&{4 z7|Tjtfx)s_%Z0IQ)^g#C(&TbtPsPWN7WoGUGv`hyF6Z$rjzd=GQs6fv6(7E#p=jUp WwTh~F>PUmDCiownot};sZh&F4|XemQ) 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 E0gr;4!T "), + subtitle=_( + " " + ), ) - if not self.settings.get("show_helper_text"): + if self.settings.get("show_helper_text"): for cat in all_units: title = str(cat[0]) subtitle = ", ".join([str(elem) for elem in cat[1:]]) @@ -50,7 +51,7 @@ def query(self, query): ) # Keyword and first unit to convert from - show what it can be converted to elif len(args) == 2: - hints = get_hints_for_category(args[1].lower()) + hints = get_hints_for_category(args[1]) self.add_item( title=_("Available conversions"), subtitle=(f"{args[0]} {args[1]} to {', '.join(hints)}"), @@ -58,10 +59,7 @@ def query(self, query): # Keyword and two units to convert from and to - try to convert elif len(args) == 3: try: - # Units are currently case insensitive. May need to change this if in future new units - # with official upper case shorthand are catered for - args[1] = args[1].lower() - args[2] = args[2].lower() + # Units are case sensitive. do_convert = gen_convert(float(args[0]), args[1], args[2]) if "Error" in do_convert: if do_convert["Error"] == _("To and from unit is the same"): @@ -132,7 +130,7 @@ def get_hints_for_category(from_unit: str): # Find the category it's in for u in gc_units.units: for u2 in gc_units.units[u]: - if u2[0] == from_unit: + if u2[0] == from_unit or u2[1] == from_unit or u2[2] == from_unit: category = str(u) for uu in gc_units.units[category]: if uu[0] != from_unit: @@ -176,9 +174,9 @@ def gen_convert(amount: float, from_unit: str, to_unit: str): return conversions for u in gc_units.units: for u2 in gc_units.units[u]: - if u2[0] == from_unit: + if u2[0] == from_unit or u2[1] == from_unit or u2[2] == from_unit: found_from = u2 - if u2[0] == to_unit: + if u2[0] == to_unit or u2[1] == to_unit or u2[2] == to_unit: found_to = u2 # If we haven't both in the same category, reset if found_to and found_from: diff --git a/plugin/units.py b/plugin/units.py index 326a6a7..1c37a52 100644 --- a/plugin/units.py +++ b/plugin/units.py @@ -21,6 +21,7 @@ # Base ["m", _("metre"), _("metres"), "x * 1", "x * 1"], # All below convert to/from base + ["dm", _("decimetre"), _("decimetres"), "x / 10", "x * 10"], ["mm", _("millimetre"), _("millimetres"), "x / 1000", "x * 1000"], ["cm", _("centimetre"), _("centimetres"), "x / 100", "x * 100"], ["km", _("kilometre"), _("kilometres"), "x / 0.001", "x * 0.001"], @@ -38,6 +39,7 @@ # All below convert to/from base ["g", _("gram"), _("grams"), "x * 1", "x * 1"], ["l", _("litre"), _("litres"), "x / 0.001", "x * 0.001"], + ["decal", _("decalitre"), _("decalitres"), "x / 0.0001", "x * 0.0001"], ["pt", _("pint US"), _("pints US"), "x / 0.002113383", "x * 0.002113383"], [ "ptimp", @@ -124,6 +126,62 @@ "x / 0.03519508", "x * 0.03519508", ], + [ + "dm3", + _("cubic decimetre"), + _("cubic decimetres"), + "x / 0.001", + "x * 0.001", + ], + [ + "mm3", + _("cubic millimetre"), + _("cubic millimetres"), + "x / 0.1000", + "x * 0.1000", + ], + [ + "cm3", + _("cubic centimetre"), + _("cubic centimetres"), + "x / 1", + "x * 1", + ], + [ + "m3", + _("cubic metre"), + _("cubic metres"), + "x / 0.000001", + "x * 0.000001", + ], + [ + "in3", + _("cubic inch"), + _("cubic inches"), + "x / 0.061024", + "x * 0.061024", + ], + [ + "ft3", + _("cubic feet"), + _("cubic feet"), + "x / 0.0000353147", + "x * 0.0000353147", + ], + [ + "buuk", + _("bushel UK"), + _("bushels UK"), + "x / 0.0000274961", + "x * 0.0000274961", + ], + [ + "buus", + _("bushel US"), + _("bushels US"), + "x / 0.0000283776", + "x * 0.0000283776", + ], ], "Area": [ # Base @@ -192,4 +250,82 @@ ["f", _("Farenheit"), _("Farenheit"), "(x - 32) / 1.8", "(x * 1.8) + 32"], ["k", _("Kelvin"), _("Kelvin"), "x - 273.15", "x + 273.15"], ], + "Speed": [ + # Base + ["km/h", _("kilometres per hour"), _("kilometres per hour"), "x * 1", "x * 1"], + [ + "m/s", + _("metres per second"), + _("metres per second"), + "x / 0.2777777778", + "x * 0.2777777778", + ], + [ + "mp/h", + _("miles per hour"), + _("miles per hour"), + "x / 0.6213711922", + "x * 0.6213711922", + ], + [ + "kt", + _("knot"), + _("knots"), + "x / 0.5399568035", + "x * 0.5399568035", + ], + ], + "Energy": [ + # Base + ["J", _("joule"), _("joules"), "x * 1", "x * 1"], + [ + "cal", + _("calorie"), + _("calories"), + "x / 0.2388459", + "x * 0.2388459", + ], + [ + "kcal", + _("kilocalorie"), + _("kilocalories"), + "x / 0.0002388459", + "x * 0.0002388459", + ], + [ + "kJ", + _("kilojoule"), + _("kilojoules"), + "x / 0.001", + "x * 0.001", + ], + [ + "MJ", + _("megajoule"), + _("megajoules"), + "x / 0.000001", + "x * 0.000001", + ], + [ + "Gj", + _("gigajoule"), + _("gigajoules"), + "x / 0.0000000010", + "x * 0.0000000010", + ], + [ + "kWh", + _("kilowatt hour"), + _("kilowatt hours"), + "x / 0.0000002778", + "x * 0.0000002778", + ], + [ + "BTU", + _("British thermal unit"), + _("British thermal units"), + "x / 0.0009478171", + "x * 0.0009478171", + ], + ], } diff --git a/plugin/utils.py b/plugin/utils.py deleted file mode 100644 index fb871ce..0000000 --- a/plugin/utils.py +++ /dev/null @@ -1,128 +0,0 @@ -import re -import plugin.units as gc_units -from plugin.extensions import _ - - -def get_hints_for_category(from_unit: str): - """Takes an input unit and returns a list of units it can be converted to - - :param from_short: unit abbreviation - :type amount: str - - :rtype: list - :return: A list of other unit abbreviations in the same category - """ - c = [] - category = "" - - # Find the category it's in - for u in gc_units.units: - for u2 in gc_units.units[u]: - if u2[0] == from_unit: - category = str(u) - for uu in gc_units.units[category]: - if uu[0] != from_unit: - c.append(uu[0]) - if category: - return c - else: - return ["no valid units"] - - -def get_all_units(short=False): - """Returns all available units as a list of lists by category - - :param short: if True only unit abbreviations are returned, default is False - :type amount: bool - - :rtype: list of lists - :return: A list of lists for each category in units. Index 0 of each internal list - is the category description - """ - - full_list = [] - for u in gc_units.units: - cat_list = [] - cat_list.append(u) - for u2 in gc_units.units[u]: - cat_list.append(u2[0] if short else f"{u2[1]} ({u2[0]})") - full_list.append(cat_list) - return full_list - - -def gen_convert(amount: float, from_unit: str, to_unit: str): - """Converts from one unit to another - - :param amount: amount of source unit to convert - :type amount: float - :param from_unit: abbreviation of unit to convert from - :type from_unit: str - :param to_unit: abbreviation of unit to convert to - :type to_unit: str - - :rtype: dict - :return: if to_unit and from_unit are valid returns a dictionary - { - "category":{category of units}, - "converted":{converted amount}, - "fromabbrev":{from unit abbreviation}, - "fromlong":{from unit long name}, - "fromplural":{from unit plural name}, - "toabbrev":{to unit abbreviation}, - "tolong":{to unit long name}, - "toplural":{to unit plural name}, - } - - else returns a dictionary with error status - {"Error": {error text}} - """ - conversions = {} - found_from = found_to = [] - if from_unit == to_unit: - conversions["Error"] = _("To and from unit is the same") - return conversions - for u in gc_units.units: - for u2 in gc_units.units[u]: - if u2[0] == from_unit: - found_from = u2 - if u2[0] == to_unit: - found_to = u2 - # If we haven't both in the same category, reset - if found_to and found_from: - found_category = u - break - else: - found_from = found_to = [] - if found_to and found_from: - base_unit_conversion = eval(found_from[3].replace("x", str(amount))) - final_conversion = eval(found_to[4].replace("x", str(base_unit_conversion))) - conversions["category"] = found_category - conversions["converted"] = final_conversion - conversions["fromabbrev"] = found_from[0] - conversions["fromlong"] = found_from[1] - conversions["fromplural"] = found_from[2] - conversions["toabbrev"] = found_to[0] - conversions["tolong"] = found_to[1] - conversions["toplural"] = found_to[2] - - else: - conversions["Error"] = _( - "Problem converting {} and {}".format(from_unit, to_unit) - ) - return conversions - - -def smart_precision(separator, amount, preferred=3): - str_amt = str(amount) - dec_places = str_amt[::-1].find(separator) - # whole number - if dec_places == -1: - return 0 - frac_part = str_amt[-dec_places::] - # fraction is just zeroes - if int(frac_part) == 0: - return 0 - fnz = re.search(r"[1-9]", frac_part).start() - if fnz < preferred: - return preferred - return fnz + 1 diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 123fc3e..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,2 +0,0 @@ -click -babel \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 26d477d..e251760 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,2 @@ -flowlauncher -python-dotenv -typing \ No newline at end of file +flox-lib==0.19.6 +python-dotenv==0.20.0 From 045428481a3b6bdd7d7434c7df900646dd85088a Mon Sep 17 00:00:00 2001 From: Damien Date: Wed, 12 Apr 2023 20:21:48 +1000 Subject: [PATCH 3/3] Update languages for new units --- commands.py | 19 +- .../translations/en/LC_MESSAGES/messages.mo | Bin 4313 -> 4239 bytes .../translations/en/LC_MESSAGES/messages.po | 380 +++++++++++++----- .../translations/zh/LC_MESSAGES/messages.mo | Bin 4081 -> 4790 bytes .../translations/zh/LC_MESSAGES/messages.po | 380 +++++++++++++----- 5 files changed, 565 insertions(+), 214 deletions(-) diff --git a/commands.py b/commands.py index fcc0a20..8ac28e3 100644 --- a/commands.py +++ b/commands.py @@ -2,25 +2,8 @@ import json import os - import click -from plugin import ( - ICON_PATH, - PLUGIN_ACTION_KEYWORD, - PLUGIN_AUTHOR, - PLUGIN_EXECUTE_FILENAME, - PLUGIN_ID, - PLUGIN_PROGRAM_LANG, - PLUGIN_URL, - __long_description__, - __package_name__, - __package_title__, - __short_description__, - __version__, - basedir, -) - @click.group() def translate(): @@ -96,4 +79,4 @@ def gen_plugin_info(): cli = click.CommandCollection(sources=[plugin, translate]) if __name__ == "__main__": - cli() \ No newline at end of file + cli() diff --git a/plugin/translations/en/LC_MESSAGES/messages.mo b/plugin/translations/en/LC_MESSAGES/messages.mo index 61586549d27577a3a97aa1c16792a33a9285563a..68e1222451c7488d7cac1c967cda1daef251164f 100644 GIT binary patch literal 4239 zcmeH|ON5fB&Em3} zNTPVagTd&*1ofZ?Bt{R!NKAYrXkzq$CLRnyJg6~vK@&YlH2(kHH9NE7(c^A<>sQ~i zzWS=B`@1=lUK04*kN<`EpL-Lf_TTg=LKGp+0B;BTz?;EAa0$2%TmU``-U7Z3=D^e7 zRPZb~8~hNQ4qgCffR{i#;uj2D_ctfcLUQK60|V`MgOk8}!O7rqkooiAG_V_F-mM`0 z%OLYV2I3JK1LF^abHQP7CU^qmeqI4*f$xI!``F2!f~@}=@K*3L$aSxR^t%SK9&Q>_ zF$LuQXJVlJPLTC1bo#|0^WE>b8f3mcka-3``ak02N1eP6WIpBe2SLU)K<GX~k$VW%GjZ-jgdeDMY$o&kC9=OLK)WB_FUd~gY< zLEifpK=$bjh!AlWL}}t9ko9~H;t>}yu+E=BuKx$fd;gb{7r@B;i$L0!fvhhNvhGzN z^LK;X-xd&|Vi!pN{U9Du#lSokWc-sL`*sXu-(Ci}pEp6C>jxnHzHssdkoA8L^4zX~ zT=yDCzbQzIeiz%d=ELU2bpgGWS&8g{(GGqI9Y?t*KqnK z$hc9E`#5V zu>ScV&vP-zd$kH=9ornsj*o*}Hw4+gqafo>fIP2L&i)q2`1hUuypz9j@+FY*K1 zS3%Y{8A*BX=Ym{kDaib*!L%Nb^_4-cR|A>Hg52j(kbOPo^v6No`{zN?vn{rV)W|y7 zv%VfTBa6xIxS0e>HX}`GlQLFEzSVJ*sl@tWUx)sIP{|;UhE-xSo%>#R+G4%t|7INc1TI%*Ol0_ zI}OZW#9$nva^VL_HW(40G+kE~iuM%hW<$1?PK78OBSre#BXGVmYT}ekHGOM%Hb*Kaf=ye$C%(FdpY8OKf7npWPq@xiHjaxCc$5g^D z$d3JGBK3%>WTO#>n|{&}n~88rCmqpFhQ)A-OWi*1>olh2lpd)wr|043X%jo<*uIm- zx^|sn%q44v^LOoNNo;4wd@N?fPbw_~=P=-BpoH}g;0M`=@zZQKuv3W*L&W*eXPiq* zM-S!y+uqW2SUXp6=Jej95LUv`h_ukGLj0b0Chi<-aXq*5;j*_eQRz#@+vHnSlEr*+rI&xu zD->m6ZE00;MIoQh!_nKNhBe<*ZNEI6yuwO^l!~iY6yTWK?i=fs6F)McZ{wtMS=sYn zC9Fe8RBQS*EUlt3!7D4jPL1r@zP&HhU2#%dm)jXO@#gZj#7W(hWYkDS(_8G8*|c|Q zBp3C{!m`|s{vDg!jVYijc->iCOs_oBz*1H{VIOFOzK*(OFytpj+1{qDdTZK#+yq{$ z-sUKXD>|x`g7lLx@hND%P$xbG?(@*` NvhVm*{6C+9e*iHxDQN%z literal 4313 zcmeH|Ux-vy9LG2f{3W^_uex*v)OwuyWBmW^ZT9O z?{|K`-#K&d4|8W65%_xs{|otlGlrJGg|mbxLS6*U2M57hzzVn+jKBrp5pXtm8q9$o zfwzL^!MngO!FKR6csqCv#3TO1z?d(Y_tz`aF>94}k2?auAQ`#K3dy z1LuM}LFTdBa?J82koz72*}r2T{Z4^AuXA?&3y}WbTKyF(U$^q#AoFWS(LBGoAoE)S z&I4D0+-DQW_>Y5WJ|OcO1G(QTAmbbbS?4j3eLZ3IC&4zz?}D%0B*Ynz_rDL$yeH!z z`*#Rj3?2n}|33lQr%NDQ#E&3S7C(W^=XVf~n2jWv=X?y@|3Q%VewpQ?R$m6W ( z$UL6~ng2eJ`y2pS=c^#&9|IZpZ4i$*je&8_g7p6kWdAOJ?B8XOb^QYJd}l&QyZIpH z1t9BK2J-w?g50+cq}?FMe71w!=Sh%#@a%d3GM_zGKMpe9e#?U(;~fDR=S`6IZ&~@2 zmEQxo-^W&e4y50wAnU(qf-yf5gGr2ZLz^$ksUoIy zqcTGe$LXw+#9^9%^tCi2N@_P$V*5}UHG>vA;s9j{*GsZN3lDkwp)yc3r%=~xvXNIR zY#$=@6s4BXR+KWL64d>&ME}wENw-!d4VyMCVWwzl6~{(Y-5|hmO-8aZma|!le?!5w z#0}Fy3!I@r#~akbkGzp|P+E-oL7dt)CYdU00(I$3i@;}B(ou_S)vknopaci#{UGo& z%jVRotq(1%W7;8+j#|`wT$#xlQwdd&E%jw0_3$cZqZWJWZqnkLi7-khE#6kfislqI zzIog?XmrCUJyN@zo`;>MO>CK?d@D_M?FPl9N!AQ&Z`;w3*v^*uq|bz#lp712V*$Sr zC5*cZzt&oe-)*yjtx6OO5$8jjDJBgaEtLE3^@gTpwRH!(oZfpR!b~`7ktUjDh+iar zuDfvoo&K`3BYVA+q%7nM`4zcssum~4*`lj{+1XI9YG*hu$+A+F#N8XHiFMTwFQ>d0 zhq=M6!%k14(l?OP>l#&(#g1apDHNQJ)v{wvsaRZID0Fnd(AlQOe7?q-b{$RurYqo5 zDz3`x23&2N;lzz};F>sT-Bxz}R|;!$18!8UyH#whqDjFSR&Gd*>>3zY7x?)&sjkfp z26epFoQ-i3>XM9Vsi?b)oidwtFOB5=-Lmj-ZcG1`zGhZTowz&qFJi@dmu*I`Mn-sPKI_HM;X+SxEsk{ftSWHG-c dU&u{=C#Js>_@t!2-0APc^moF3JpSMB#6OZ;M6Cb- diff --git a/plugin/translations/en/LC_MESSAGES/messages.po b/plugin/translations/en/LC_MESSAGES/messages.po index e2b0cf6..0e06881 100644 --- a/plugin/translations/en/LC_MESSAGES/messages.po +++ b/plugin/translations/en/LC_MESSAGES/messages.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: 1.1.3\n" +"Project-Id-Version: 2.0.0\n" "Report-Msgid-Bugs-To: deefrawley@gmail.com\n" -"POT-Creation-Date: 2022-11-08 09:22+1100\n" +"POT-Creation-Date: 2023-04-12 19:52+1000\n" "PO-Revision-Date: 2020-12-13 20:26+1100\n" "Last-Translator: deefrawley \n" "Language: en\n" @@ -18,34 +18,45 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.9.1\n" -#: plugin/ui.py:48 plugin/ui.py:108 +#: plugin/general_converter.py:24 plugin/general_converter.py:92 msgid "General Converter" msgstr "General Converter" -#: plugin/ui.py:49 plugin/ui.py:109 -msgid " " +#: plugin/general_converter.py:25 +#, fuzzy +msgid "" +" " msgstr " " -#: plugin/ui.py:67 +#: plugin/general_converter.py:56 msgid "Available conversions" msgstr "Available conversions" -#: plugin/ui.py:81 +#: plugin/general_converter.py:65 plugin/general_converter.py:173 +msgid "To and from unit is the same" +msgstr "To and from unit is the same" + +#: plugin/general_converter.py:67 msgid "{}" msgstr "{}" -#: plugin/ui.py:82 +#: plugin/general_converter.py:68 msgid "Choose two different units" msgstr "Choose two different units" -#: plugin/ui.py:87 plugin/ui.py:104 +#: plugin/general_converter.py:73 msgid "Error - {}" msgstr "Error - {}" -#: plugin/ui.py:88 +#: plugin/general_converter.py:74 msgid "Check documentation for accepted units" msgstr "Check documentation for accepted units" +#: plugin/general_converter.py:93 +msgid " " +msgstr " " + #: plugin/units.py:20 msgid "Distance" msgstr "Distance" @@ -59,343 +70,516 @@ msgid "metres" msgstr "metres" #: plugin/units.py:24 +#, fuzzy +msgid "decimetre" +msgstr "centimetre" + +#: plugin/units.py:24 +#, fuzzy +msgid "decimetres" +msgstr "centimetres" + +#: plugin/units.py:25 msgid "millimetre" msgstr "millimetre" -#: plugin/units.py:24 +#: plugin/units.py:25 msgid "millimetres" msgstr "millimetres" -#: plugin/units.py:25 +#: plugin/units.py:26 msgid "centimetre" msgstr "centimetre" -#: plugin/units.py:25 +#: plugin/units.py:26 msgid "centimetres" msgstr "centimetres" -#: plugin/units.py:26 +#: plugin/units.py:27 msgid "kilometre" msgstr "kilometre" -#: plugin/units.py:26 +#: plugin/units.py:27 msgid "kilometres" msgstr "kilometres" -#: plugin/units.py:27 +#: plugin/units.py:28 msgid "inch" msgstr "inch" -#: plugin/units.py:27 +#: plugin/units.py:28 msgid "inches" msgstr "inches" -#: plugin/units.py:28 +#: plugin/units.py:29 msgid "foot" msgstr "foot" -#: plugin/units.py:28 +#: plugin/units.py:29 msgid "feet" msgstr "feet" -#: plugin/units.py:29 +#: plugin/units.py:30 msgid "yard" msgstr "yard" -#: plugin/units.py:29 +#: plugin/units.py:30 msgid "yards" msgstr "yards" -#: plugin/units.py:30 +#: plugin/units.py:31 msgid "mile" msgstr "mile" -#: plugin/units.py:30 +#: plugin/units.py:31 msgid "miles" msgstr "miles" -#: plugin/units.py:32 +#: plugin/units.py:33 msgid "Volume" msgstr "Volume" -#: plugin/units.py:37 +#: plugin/units.py:38 msgid "millilitre" msgstr "millilitre" -#: plugin/units.py:37 +#: plugin/units.py:38 msgid "millilitres" msgstr "millilitres" -#: plugin/units.py:39 plugin/units.py:160 +#: plugin/units.py:40 plugin/units.py:218 msgid "gram" msgstr "gram" -#: plugin/units.py:39 plugin/units.py:160 +#: plugin/units.py:40 plugin/units.py:218 msgid "grams" msgstr "grams" -#: plugin/units.py:40 +#: plugin/units.py:41 msgid "litre" msgstr "litre" -#: plugin/units.py:40 +#: plugin/units.py:41 msgid "litres" msgstr "litres" -#: plugin/units.py:41 +#: plugin/units.py:42 +#, fuzzy +msgid "decalitre" +msgstr "litre" + +#: plugin/units.py:42 +#, fuzzy +msgid "decalitres" +msgstr "litres" + +#: plugin/units.py:43 msgid "pint US" msgstr "pint US" -#: plugin/units.py:41 +#: plugin/units.py:43 msgid "pints US" msgstr "pints US" -#: plugin/units.py:44 +#: plugin/units.py:46 msgid "pint Imperial" msgstr "pint Imperial" -#: plugin/units.py:45 +#: plugin/units.py:47 msgid "pints Imperial" msgstr "pints Imperial" -#: plugin/units.py:49 +#: plugin/units.py:51 msgid "quart US" msgstr "quart US" -#: plugin/units.py:49 +#: plugin/units.py:51 msgid "quarts US" msgstr "quarts US" -#: plugin/units.py:52 +#: plugin/units.py:54 msgid "quart Imperial" msgstr "quart Imperial" -#: plugin/units.py:53 +#: plugin/units.py:55 msgid "quarts Imperial" msgstr "quarts Imperial" -#: plugin/units.py:59 +#: plugin/units.py:61 msgid "cup US" msgstr "cup US" -#: plugin/units.py:60 +#: plugin/units.py:62 msgid "cups US" msgstr "cups US" -#: plugin/units.py:66 +#: plugin/units.py:68 msgid "cup Imperial" msgstr "cup Imperial" -#: plugin/units.py:67 +#: plugin/units.py:69 msgid "cups Imperial" msgstr "cups Imperial" -#: plugin/units.py:73 +#: plugin/units.py:75 msgid "tablespoon US" msgstr "tablespoon US" -#: plugin/units.py:74 +#: plugin/units.py:76 msgid "tabelspoons US" msgstr "tabelspoons US" -#: plugin/units.py:80 +#: plugin/units.py:82 msgid "tablespoon Imperial" msgstr "tablespoon Imperial" -#: plugin/units.py:81 +#: plugin/units.py:83 msgid "tabelspoons Imperial" msgstr "tabelspoons Imperial" -#: plugin/units.py:87 +#: plugin/units.py:89 msgid "teaspoon US" msgstr "teaspoon US" -#: plugin/units.py:88 +#: plugin/units.py:90 msgid "teaspoons US" msgstr "teaspoons US" -#: plugin/units.py:94 +#: plugin/units.py:96 msgid "teaspoon Imperial" msgstr "teaspoon Imperial" -#: plugin/units.py:95 +#: plugin/units.py:97 msgid "teaspoons Imperial" msgstr "teaspoons Imperial" -#: plugin/units.py:101 +#: plugin/units.py:103 msgid "gallon US" msgstr "gallon US" -#: plugin/units.py:102 +#: plugin/units.py:104 msgid "gallons US" msgstr "gallons US" -#: plugin/units.py:108 +#: plugin/units.py:110 msgid "gallon Imperial" msgstr "gallon Imperial" -#: plugin/units.py:109 +#: plugin/units.py:111 msgid "gallons Imperial" msgstr "gallons Imperial" -#: plugin/units.py:115 +#: plugin/units.py:117 msgid "fluid ounce US" msgstr "fluid ounce US" -#: plugin/units.py:116 +#: plugin/units.py:118 msgid "fluid ounces US" msgstr "fluid ounces US" -#: plugin/units.py:122 +#: plugin/units.py:124 msgid "fluid ounce Imperial" msgstr "fluid ounce Imperial" -#: plugin/units.py:123 +#: plugin/units.py:125 msgid "fluid ounces Imperial" msgstr "fluid ounces Imperial" -#: plugin/units.py:130 +#: plugin/units.py:131 +#, fuzzy +msgid "cubic decimetre" +msgstr "centimetre" + +#: plugin/units.py:132 +#, fuzzy +msgid "cubic decimetres" +msgstr "centimetres" + +#: plugin/units.py:138 +#, fuzzy +msgid "cubic millimetre" +msgstr "millimetre" + +#: plugin/units.py:139 +#, fuzzy +msgid "cubic millimetres" +msgstr "millimetres" + +#: plugin/units.py:145 +#, fuzzy +msgid "cubic centimetre" +msgstr "centimetre" + +#: plugin/units.py:146 +#, fuzzy +msgid "cubic centimetres" +msgstr "centimetres" + +#: plugin/units.py:152 +#, fuzzy +msgid "cubic metre" +msgstr "centimetre" + +#: plugin/units.py:153 +#, fuzzy +msgid "cubic metres" +msgstr "centimetres" + +#: plugin/units.py:159 +msgid "cubic inch" +msgstr "" + +#: plugin/units.py:160 +#, fuzzy +msgid "cubic inches" +msgstr "inches" + +#: plugin/units.py:166 plugin/units.py:167 +msgid "cubic feet" +msgstr "" + +#: plugin/units.py:173 +msgid "bushel UK" +msgstr "" + +#: plugin/units.py:174 +msgid "bushels UK" +msgstr "" + +#: plugin/units.py:180 +msgid "bushel US" +msgstr "" + +#: plugin/units.py:181 +msgid "bushels US" +msgstr "" + +#: plugin/units.py:188 msgid "square metre" msgstr "square metre" -#: plugin/units.py:130 +#: plugin/units.py:188 msgid "square metres" msgstr "square metres" -#: plugin/units.py:131 +#: plugin/units.py:189 msgid "hectare" msgstr "hectare" -#: plugin/units.py:131 +#: plugin/units.py:189 msgid "hectares" msgstr "hectares" -#: plugin/units.py:132 +#: plugin/units.py:190 msgid "acre" msgstr "acre" -#: plugin/units.py:132 +#: plugin/units.py:190 msgid "acres" msgstr "acres" -#: plugin/units.py:135 +#: plugin/units.py:193 msgid "square centimetre" msgstr "square centimetre" -#: plugin/units.py:136 +#: plugin/units.py:194 msgid "square centimetres" msgstr "square centimetres" -#: plugin/units.py:142 +#: plugin/units.py:200 msgid "square kilometre" msgstr "square kilometre" -#: plugin/units.py:143 +#: plugin/units.py:201 msgid "square kilometres" msgstr "square kilometres" -#: plugin/units.py:147 +#: plugin/units.py:205 msgid "square inch" msgstr "square inch" -#: plugin/units.py:147 +#: plugin/units.py:205 msgid "square inches" msgstr "square inches" -#: plugin/units.py:150 +#: plugin/units.py:208 msgid "square mile" msgstr "square mile" -#: plugin/units.py:151 +#: plugin/units.py:209 msgid "square miles" msgstr "square miles" -#: plugin/units.py:155 +#: plugin/units.py:213 msgid "square foot" msgstr "square foot" -#: plugin/units.py:155 +#: plugin/units.py:213 msgid "square feet" msgstr "square feet" -#: plugin/units.py:156 +#: plugin/units.py:214 msgid "square yard" msgstr "square yard" -#: plugin/units.py:156 +#: plugin/units.py:214 msgid "square yards" msgstr "square yards" -#: plugin/units.py:162 +#: plugin/units.py:220 msgid "kilogram" msgstr "kilogram" -#: plugin/units.py:162 +#: plugin/units.py:220 msgid "kilograms" msgstr "kilograms" -#: plugin/units.py:163 +#: plugin/units.py:221 msgid "pound" msgstr "pound" -#: plugin/units.py:163 +#: plugin/units.py:221 msgid "pounds" msgstr "pounds" -#: plugin/units.py:164 +#: plugin/units.py:222 msgid "ounce" msgstr "ounce" -#: plugin/units.py:164 +#: plugin/units.py:222 msgid "ounces" msgstr "ounces" -#: plugin/units.py:165 +#: plugin/units.py:223 msgid "stone" msgstr "stone" -#: plugin/units.py:168 +#: plugin/units.py:226 msgid "tonne" msgstr "tonne" -#: plugin/units.py:169 +#: plugin/units.py:227 msgid "tonnes" msgstr "tonnes" -#: plugin/units.py:175 +#: plugin/units.py:233 msgid "US ton" msgstr "US ton" -#: plugin/units.py:176 +#: plugin/units.py:234 msgid "US tons" msgstr "US tons" -#: plugin/units.py:182 +#: plugin/units.py:240 msgid "Imperial ton" msgstr "Imperial ton" -#: plugin/units.py:183 +#: plugin/units.py:241 msgid "Imperial tons" msgstr "Imperial tons" -#: plugin/units.py:190 +#: plugin/units.py:248 msgid "Celsius" msgstr "Celsius" -#: plugin/units.py:192 +#: plugin/units.py:250 msgid "Farenheit" msgstr "Farenheit" -#: plugin/units.py:193 +#: plugin/units.py:251 msgid "Kelvin" msgstr "Kelvin" -#: plugin/utils.py:82 -msgid "To and from unit is the same" -msgstr "To and from unit is the same" +#: plugin/units.py:255 +#, fuzzy +msgid "kilometres per hour" +msgstr "kilometres" + +#: plugin/units.py:258 plugin/units.py:259 +msgid "metres per second" +msgstr "" + +#: plugin/units.py:265 plugin/units.py:266 +msgid "miles per hour" +msgstr "" + +#: plugin/units.py:272 +msgid "knot" +msgstr "" + +#: plugin/units.py:273 +msgid "knots" +msgstr "" + +#: plugin/units.py:280 +#, fuzzy +msgid "joule" +msgstr "ounce" + +#: plugin/units.py:280 +#, fuzzy +msgid "joules" +msgstr "ounces" + +#: plugin/units.py:283 +msgid "calorie" +msgstr "" + +#: plugin/units.py:284 +#, fuzzy +msgid "calories" +msgstr "hectares" + +#: plugin/units.py:290 +msgid "kilocalorie" +msgstr "" + +#: plugin/units.py:291 +#, fuzzy +msgid "kilocalories" +msgstr "kilometres" + +#: plugin/units.py:297 +msgid "kilojoule" +msgstr "" + +#: plugin/units.py:298 +#, fuzzy +msgid "kilojoules" +msgstr "kilometres" + +#: plugin/units.py:304 +msgid "megajoule" +msgstr "" + +#: plugin/units.py:305 +msgid "megajoules" +msgstr "" + +#: plugin/units.py:311 +msgid "gigajoule" +msgstr "" + +#: plugin/units.py:312 +msgid "gigajoules" +msgstr "" + +#: plugin/units.py:318 +msgid "kilowatt hour" +msgstr "" + +#: plugin/units.py:319 +msgid "kilowatt hours" +msgstr "" + +#: plugin/units.py:325 +msgid "British thermal unit" +msgstr "" -#: plugin/utils.py:110 -msgid "Problem converting {} and {}" -msgstr "Problem converting {} and {}" +#: plugin/units.py:326 +msgid "British thermal units" +msgstr "" +#~ msgid "Problem converting {} and {}" +#~ msgstr "Problem converting {} and {}" diff --git a/plugin/translations/zh/LC_MESSAGES/messages.mo b/plugin/translations/zh/LC_MESSAGES/messages.mo index 8365bb6d06b1ecc35f669e0ba612abc200ed6003..b646cd1a19f7920fd37a2de840b5a9f8756bfa31 100644 GIT binary patch literal 4790 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 delta 1790 zcmYMze`wTo9LMp`bhg{vcIVQSO>31Y>~wi&MJ}TykwylR5N24dJasW|bemF`9!PFM zn}uJ*8I`*B#|mx8g+f~BA4Mzz|1kea2WqpeDAPauqZagh-Coi0z0c$G{``7>KA-R1 z@%ygdl^>}o-52=0#CHzgnNt=0|Eatsgfw9l&cbFa!{=~5zKD0=Zj9j}tiVsP9KXOB z_%&AIS**f~$deDhQ7Z8b8)tQ@VIeBf6335VDe-cghAU8sp26w37L{NFYX0k}L~kHZ z=%Ud4Jvb91tR{aLq@t6Zz&QSZ8hFw1Wz1ORNumA+ zP#aq6_GZ+2Pf7BJHB_|VdelOjQ4_L`w>sXAT5y-!yHWFcQ8&=%c);-xYQ2-F_0FJf zSj+(b>7K=n^$yXvn&-B2Cs1W5|L+Xt}*SD-es&Th0hRN|ee z8|*>N`>34z*E<{XfK#XihEeV39ba*L4Yk1u)H|HQ@wLI*@K&6UO4Ni(uo8vUCc|2k<84Z7OM9evnS62iy0koF|AG;uA3#%Hhr+prGzyS;!)_$9K(@Ga`M zb=L7!`=|XYPoaN+ZsE2(tN0Q!va*|Mw@o~L-tYognimR zYoE6-+f6oWx1tX8mhCFa`+wgJAD}icUtX!T*FG{5rEq=Iu@zSPrI+;op zu2;TL66LB7){cF3r5bZ?ImC*sXjqkH;(IaUahMBl`BMJ$iN^0TqSga0x1?y>Rio-j$FcE+KSe*w>W*Ps9Z diff --git a/plugin/translations/zh/LC_MESSAGES/messages.po b/plugin/translations/zh/LC_MESSAGES/messages.po index 2510fd2..a7f3aa3 100644 --- a/plugin/translations/zh/LC_MESSAGES/messages.po +++ b/plugin/translations/zh/LC_MESSAGES/messages.po @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: 1.1.3\n" +"Project-Id-Version: 2.0.0\n" "Report-Msgid-Bugs-To: deefrawley@gmail.com\n" -"POT-Creation-Date: 2022-11-08 09:22+1100\n" +"POT-Creation-Date: 2023-04-12 19:52+1000\n" "PO-Revision-Date: 2021-06-07 15:16+1000\n" "Last-Translator: deefrawley \n" "Language: zh\n" @@ -18,34 +18,45 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.9.1\n" -#: plugin/ui.py:48 plugin/ui.py:108 +#: plugin/general_converter.py:24 plugin/general_converter.py:92 msgid "General Converter" msgstr "通用单位换算器" -#: plugin/ui.py:49 plugin/ui.py:109 -msgid " " +#: plugin/general_converter.py:25 +#, fuzzy +msgid "" +" " msgstr "<热键> <量> <源单元> <目的地单位>" -#: plugin/ui.py:67 +#: plugin/general_converter.py:56 msgid "Available conversions" msgstr "可用转换" -#: plugin/ui.py:81 +#: plugin/general_converter.py:65 plugin/general_converter.py:173 +msgid "To and from unit is the same" +msgstr "源单元和目标单元相同" + +#: plugin/general_converter.py:67 msgid "{}" msgstr "" -#: plugin/ui.py:82 +#: plugin/general_converter.py:68 msgid "Choose two different units" msgstr "选择两个不同的单位" -#: plugin/ui.py:87 plugin/ui.py:104 +#: plugin/general_converter.py:73 msgid "Error - {}" msgstr "错误 - {}" -#: plugin/ui.py:88 +#: plugin/general_converter.py:74 msgid "Check documentation for accepted units" msgstr "检查文档以获取正确的度量单位" +#: plugin/general_converter.py:93 +msgid " " +msgstr "<热键> <量> <源单元> <目的地单位>" + #: plugin/units.py:20 msgid "Distance" msgstr "距离" @@ -59,343 +70,516 @@ msgid "metres" msgstr "仪表" #: plugin/units.py:24 +#, fuzzy +msgid "decimetre" +msgstr "厘米" + +#: plugin/units.py:24 +#, fuzzy +msgid "decimetres" +msgstr "厘米" + +#: plugin/units.py:25 msgid "millimetre" msgstr "毫米" -#: plugin/units.py:24 +#: plugin/units.py:25 msgid "millimetres" msgstr "毫米" -#: plugin/units.py:25 +#: plugin/units.py:26 msgid "centimetre" msgstr "厘米" -#: plugin/units.py:25 +#: plugin/units.py:26 msgid "centimetres" msgstr "厘米" -#: plugin/units.py:26 +#: plugin/units.py:27 msgid "kilometre" msgstr "公里" -#: plugin/units.py:26 +#: plugin/units.py:27 msgid "kilometres" msgstr "公里" -#: plugin/units.py:27 +#: plugin/units.py:28 msgid "inch" msgstr "英寸" -#: plugin/units.py:27 +#: plugin/units.py:28 msgid "inches" msgstr "英寸" -#: plugin/units.py:28 +#: plugin/units.py:29 msgid "foot" msgstr "丈" -#: plugin/units.py:28 +#: plugin/units.py:29 msgid "feet" msgstr "丈" -#: plugin/units.py:29 +#: plugin/units.py:30 msgid "yard" msgstr "码尺" -#: plugin/units.py:29 +#: plugin/units.py:30 msgid "yards" msgstr "码尺" -#: plugin/units.py:30 +#: plugin/units.py:31 msgid "mile" msgstr "英里" -#: plugin/units.py:30 +#: plugin/units.py:31 msgid "miles" msgstr "英里" -#: plugin/units.py:32 +#: plugin/units.py:33 msgid "Volume" msgstr "量" -#: plugin/units.py:37 +#: plugin/units.py:38 msgid "millilitre" msgstr "毫升" -#: plugin/units.py:37 +#: plugin/units.py:38 msgid "millilitres" msgstr "毫升" -#: plugin/units.py:39 plugin/units.py:160 +#: plugin/units.py:40 plugin/units.py:218 msgid "gram" msgstr "公克" -#: plugin/units.py:39 plugin/units.py:160 +#: plugin/units.py:40 plugin/units.py:218 msgid "grams" msgstr "公克" -#: plugin/units.py:40 +#: plugin/units.py:41 msgid "litre" msgstr "升" -#: plugin/units.py:40 +#: plugin/units.py:41 msgid "litres" msgstr "升" -#: plugin/units.py:41 +#: plugin/units.py:42 +#, fuzzy +msgid "decalitre" +msgstr "升" + +#: plugin/units.py:42 +#, fuzzy +msgid "decalitres" +msgstr "升" + +#: plugin/units.py:43 msgid "pint US" msgstr "品脱 US" -#: plugin/units.py:41 +#: plugin/units.py:43 msgid "pints US" msgstr "品脱 US" -#: plugin/units.py:44 +#: plugin/units.py:46 msgid "pint Imperial" msgstr "英品脱" -#: plugin/units.py:45 +#: plugin/units.py:47 msgid "pints Imperial" msgstr "英品脱" -#: plugin/units.py:49 +#: plugin/units.py:51 msgid "quart US" msgstr "夸脱 US" -#: plugin/units.py:49 +#: plugin/units.py:51 msgid "quarts US" msgstr "夸脱 US" -#: plugin/units.py:52 +#: plugin/units.py:54 msgid "quart Imperial" msgstr "英夸脱" -#: plugin/units.py:53 +#: plugin/units.py:55 msgid "quarts Imperial" msgstr "英夸脱" -#: plugin/units.py:59 +#: plugin/units.py:61 msgid "cup US" msgstr "杯 US" -#: plugin/units.py:60 +#: plugin/units.py:62 msgid "cups US" msgstr "杯 US" -#: plugin/units.py:66 +#: plugin/units.py:68 msgid "cup Imperial" msgstr "英杯" -#: plugin/units.py:67 +#: plugin/units.py:69 msgid "cups Imperial" msgstr "英杯" -#: plugin/units.py:73 +#: plugin/units.py:75 msgid "tablespoon US" msgstr "汤匙 US" -#: plugin/units.py:74 +#: plugin/units.py:76 msgid "tabelspoons US" msgstr "汤匙 US" -#: plugin/units.py:80 +#: plugin/units.py:82 msgid "tablespoon Imperial" msgstr "英汤匙" -#: plugin/units.py:81 +#: plugin/units.py:83 msgid "tabelspoons Imperial" msgstr "英汤匙" -#: plugin/units.py:87 +#: plugin/units.py:89 msgid "teaspoon US" msgstr "茶匙 US" -#: plugin/units.py:88 +#: plugin/units.py:90 msgid "teaspoons US" msgstr "茶匙 US" -#: plugin/units.py:94 +#: plugin/units.py:96 msgid "teaspoon Imperial" msgstr "英茶匙" -#: plugin/units.py:95 +#: plugin/units.py:97 msgid "teaspoons Imperial" msgstr "英茶匙" -#: plugin/units.py:101 +#: plugin/units.py:103 msgid "gallon US" msgstr "加仑 US" -#: plugin/units.py:102 +#: plugin/units.py:104 msgid "gallons US" msgstr "加仑 US" -#: plugin/units.py:108 +#: plugin/units.py:110 msgid "gallon Imperial" msgstr "英加仑" -#: plugin/units.py:109 +#: plugin/units.py:111 msgid "gallons Imperial" msgstr "英加仑" -#: plugin/units.py:115 +#: plugin/units.py:117 msgid "fluid ounce US" msgstr "液盎司 US" -#: plugin/units.py:116 +#: plugin/units.py:118 msgid "fluid ounces US" msgstr "液盎司 US" -#: plugin/units.py:122 +#: plugin/units.py:124 msgid "fluid ounce Imperial" msgstr "英液盎司" -#: plugin/units.py:123 +#: plugin/units.py:125 msgid "fluid ounces Imperial" msgstr "英液盎司" -#: plugin/units.py:130 +#: plugin/units.py:131 +#, fuzzy +msgid "cubic decimetre" +msgstr "立方分米" + +#: plugin/units.py:132 +#, fuzzy +msgid "cubic decimetres" +msgstr "立方分米" + +#: plugin/units.py:138 +#, fuzzy +msgid "cubic millimetre" +msgstr "立方毫米" + +#: plugin/units.py:139 +#, fuzzy +msgid "cubic millimetres" +msgstr "立方毫米" + +#: plugin/units.py:145 +#, fuzzy +msgid "cubic centimetre" +msgstr "立方厘米" + +#: plugin/units.py:146 +#, fuzzy +msgid "cubic centimetres" +msgstr "立方厘米" + +#: plugin/units.py:152 +#, fuzzy +msgid "cubic metre" +msgstr "立方米" + +#: plugin/units.py:153 +#, fuzzy +msgid "cubic metres" +msgstr "立方米" + +#: plugin/units.py:159 +msgid "cubic inch" +msgstr "立方英寸" + +#: plugin/units.py:160 +#, fuzzy +msgid "cubic inches" +msgstr "英寸" + +#: plugin/units.py:166 plugin/units.py:167 +msgid "cubic feet" +msgstr "立方英尺" + +#: plugin/units.py:173 +msgid "bushel UK" +msgstr "蒲式耳 英国" + +#: plugin/units.py:174 +msgid "bushels UK" +msgstr "蒲式耳 英国" + +#: plugin/units.py:180 +msgid "bushel US" +msgstr "蒲式耳 美国" + +#: plugin/units.py:181 +msgid "bushels US" +msgstr "蒲式耳 美国" + +#: plugin/units.py:188 msgid "square metre" msgstr "平方米" -#: plugin/units.py:130 +#: plugin/units.py:188 msgid "square metres" msgstr "平方米" -#: plugin/units.py:131 +#: plugin/units.py:189 msgid "hectare" msgstr "公顷" -#: plugin/units.py:131 +#: plugin/units.py:189 msgid "hectares" msgstr "公顷" -#: plugin/units.py:132 +#: plugin/units.py:190 msgid "acre" msgstr "英亩" -#: plugin/units.py:132 +#: plugin/units.py:190 msgid "acres" msgstr "英亩" -#: plugin/units.py:135 +#: plugin/units.py:193 msgid "square centimetre" msgstr "平方厘米" -#: plugin/units.py:136 +#: plugin/units.py:194 msgid "square centimetres" msgstr "平方厘米" -#: plugin/units.py:142 +#: plugin/units.py:200 msgid "square kilometre" msgstr "平方公里" -#: plugin/units.py:143 +#: plugin/units.py:201 msgid "square kilometres" msgstr "平方公里" -#: plugin/units.py:147 +#: plugin/units.py:205 msgid "square inch" msgstr "平方英寸" -#: plugin/units.py:147 +#: plugin/units.py:205 msgid "square inches" msgstr "平方英寸" -#: plugin/units.py:150 +#: plugin/units.py:208 msgid "square mile" msgstr "平方英里" -#: plugin/units.py:151 +#: plugin/units.py:209 msgid "square miles" msgstr "平方英里" -#: plugin/units.py:155 +#: plugin/units.py:213 msgid "square foot" msgstr "平方英尺" -#: plugin/units.py:155 +#: plugin/units.py:213 msgid "square feet" msgstr "平方英尺" -#: plugin/units.py:156 +#: plugin/units.py:214 msgid "square yard" msgstr "平方码" -#: plugin/units.py:156 +#: plugin/units.py:214 msgid "square yards" msgstr "平方码" -#: plugin/units.py:162 +#: plugin/units.py:220 msgid "kilogram" msgstr "公斤" -#: plugin/units.py:162 +#: plugin/units.py:220 msgid "kilograms" msgstr "公斤" -#: plugin/units.py:163 +#: plugin/units.py:221 msgid "pound" msgstr "磅" -#: plugin/units.py:163 +#: plugin/units.py:221 msgid "pounds" msgstr "磅" -#: plugin/units.py:164 +#: plugin/units.py:222 msgid "ounce" msgstr "盎司" -#: plugin/units.py:164 +#: plugin/units.py:222 msgid "ounces" msgstr "盎司" -#: plugin/units.py:165 +#: plugin/units.py:223 msgid "stone" msgstr "石头" -#: plugin/units.py:168 +#: plugin/units.py:226 msgid "tonne" msgstr "公吨" -#: plugin/units.py:169 +#: plugin/units.py:227 msgid "tonnes" msgstr "公吨" -#: plugin/units.py:175 +#: plugin/units.py:233 msgid "US ton" msgstr "美吨" -#: plugin/units.py:176 +#: plugin/units.py:234 msgid "US tons" msgstr "美吨" -#: plugin/units.py:182 +#: plugin/units.py:240 msgid "Imperial ton" msgstr "英制吨" -#: plugin/units.py:183 +#: plugin/units.py:241 msgid "Imperial tons" msgstr "英制吨" -#: plugin/units.py:190 +#: plugin/units.py:248 msgid "Celsius" msgstr "摄氏" -#: plugin/units.py:192 +#: plugin/units.py:250 msgid "Farenheit" msgstr "华氏度" -#: plugin/units.py:193 +#: plugin/units.py:251 msgid "Kelvin" msgstr "开尔文" -#: plugin/utils.py:82 -msgid "To and from unit is the same" -msgstr "源单元和目标单元相同" +#: plugin/units.py:255 +#, fuzzy +msgid "kilometres per hour" +msgstr "公里每小时" + +#: plugin/units.py:258 plugin/units.py:259 +msgid "metres per second" +msgstr "米每秒" + +#: plugin/units.py:265 plugin/units.py:266 +msgid "miles per hour" +msgstr "英里每小时" + +#: plugin/units.py:272 +msgid "knot" +msgstr "海里" + +#: plugin/units.py:273 +msgid "knots" +msgstr "海里" + +#: plugin/units.py:280 +#, fuzzy +msgid "joule" +msgstr "焦耳" + +#: plugin/units.py:280 +#, fuzzy +msgid "joules" +msgstr "焦耳" + +#: plugin/units.py:283 +msgid "calorie" +msgstr "卡路里" + +#: plugin/units.py:284 +#, fuzzy +msgid "calories" +msgstr "卡路里" + +#: plugin/units.py:290 +msgid "kilocalorie" +msgstr "大卡" + +#: plugin/units.py:291 +#, fuzzy +msgid "kilocalories" +msgstr "大卡" + +#: plugin/units.py:297 +msgid "kilojoule" +msgstr "" + +#: plugin/units.py:298 +#, fuzzy +msgid "kilojoules" +msgstr "千焦耳" + +#: plugin/units.py:304 +msgid "megajoule" +msgstr "兆焦耳" + +#: plugin/units.py:305 +msgid "megajoules" +msgstr "兆焦耳" + +#: plugin/units.py:311 +msgid "gigajoule" +msgstr "千兆焦耳" + +#: plugin/units.py:312 +msgid "gigajoules" +msgstr "千兆焦耳" + +#: plugin/units.py:318 +msgid "kilowatt hour" +msgstr "" + +#: plugin/units.py:319 +msgid "kilowatt hours" +msgstr "千瓦时" + +#: plugin/units.py:325 +msgid "British thermal unit" +msgstr "英国热量单位" -#: plugin/utils.py:110 -msgid "Problem converting {} and {}" -msgstr "转换问题 {} 和 {}" +#: plugin/units.py:326 +msgid "British thermal units" +msgstr "英国热量单位" +#~ msgid "Problem converting {} and {}" +#~ msgstr "转换问题 {} 和 {}"