diff --git a/.gitignore b/.gitignore index 99530a5..8b16396 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.cache + # Python snippets from gitignore on github *.py[co] diff --git a/README.md b/README.md index 82dc7c6..bc9376c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Convert between different units offline in [Alfred 2 & 3][alfred]. ![][demo] -Alfred-Convert uses a [built-in library][pintdocs] for lightning fast conversions. +Alfred-Convert uses a [built-in library][pintdocs] for lightning-fast conversions. You can also add your own custom units. @@ -14,6 +14,10 @@ You can also add your own custom units. - [Downloading](#downloading) - [Usage](#usage) + - [Conversions](#conversions) + - [Configuration](#configuration) + - [Active currencies](#active-currencies) + - [Custom units](#custom-units) - [Supported units](#supported-units) - [Supported currencies](#supported-currencies) - [Adding custom units](#adding-custom-units) @@ -24,16 +28,35 @@ You can also add your own custom units. Downloading ----------- -Download from [GitHub][ghreleases] or [Packal.org][packal]. +Download from [GitHub releases][ghreleases]. + +**Note**: Version 3.0 and above only supports Alfred 3. If you're still using Alfred 2, please download [v2.6][v2.6]. Usage ----- +- `conv []` — Perform a conversion + - `↩` or `⌘C` — Copy the result to the pasteboard + - `⌘↩` — Add/remove destination unit as default for this dimensionality + - `⌘L` — Show result in Alfred's Large Type window +- `convinfo` — View help file and information about the workflow, or edit custom units and active currencies + - `View Help File` — Open this page in your browser + - `View All Supported Currencies` — View/filter the list of all supported currencies in Alfred + - `Edit Active Currencies` — Edit the list of active currencies in your default text editor + - `Edit Custom Units` — Edit the list of custom currencies in your default text editor + ### Conversions ### -The syntax is simple: the quantity, the unit you want to convert from then the unit you want to convert to. For example: +- `conv []` — Perform a conversion + - `↩` or `⌘C` — Copy the result to the pasteboard + - `⌘↩` — Add/remove destination unit as default for this dimensionality + - `⌘L` — Show result in Alfred's Large Type window + +If no destination unit is specified, any defaults you've saved will be used (that aren't the same as the source unit). + +The syntax is simple: the quantity, the unit you want to convert from then (optionally) the unit you want to convert to. For example: - `conv 128 mph kph` - `conv 72in cm` @@ -46,13 +69,38 @@ It doesn't matter if there is a space between the quantity and the units or not. Actioning an item (selecting it and hitting `↩`) will copy it to the clipboard. Using `⌘+L` will display the result in Alfred's large text window, `⌘+C` will copy the selected result to the clipboard. -### Settings ### +### Configuration ### + +The workflow is configured via the configuration sheet (`[𝓍]`) in Alfred Preferences and via a couple of text files in its data directory. + + +#### Configuration sheet #### + +Basic configuration is performed in the configuration sheet: + +| Option | Meaning | +|-----------------------|----------------------------------------------------------------------------------------------| +| `COPY_UNIT` | Include unit when copying conversion result. Any value but `0` or empty turns this option on | +| `DECIMAL_PLACES` | Number of decimal places to show in results | +| `DECIMAL_SEPARATOR` | Character to separate whole numbers and decimal fractions | +| `THOUSANDS_SEPARATOR` | Character to delimit thousands | +| `UPDATE_INTERVAL` | How often (in minutes) to update currency exchange rates | + + +#### Active currencies #### + +By default, all supported fiat currencies and a handful of the most popular cryptocurrencies are active. + +- `convinfo` + - `View All Supported Currencies` + - `Edit Active Currencies` + +Use `Edit Active Currencies` to open the list of active currencies in your default editor. Add the symbol for the currency you'd like to activate on a new line in this file. -Use `convinfo` to view the built-in help file, view/search the list of -supported currencies, change the number of decimal places shown in conversions, or edit your custom units. +You can use `View All Supported Currencies` to search for the currency you'd like to activate, then use `⌘C` on the result to copy the symbol to the pasteboard. -### Custom units ### +#### Custom units #### See [Adding custom units](#adding-custom-units). @@ -62,14 +110,14 @@ Supported units Currently, Alfred-Convert only supports [the units][pintunits] understood by the underlying [Pint][pintdocs] library plus [currencies](#supported-currencies) and a handful of additional units. -You can [your own custom units](#adding-custom-units) to the workflow. If you think they'd be useful to everyone, please create a corresponding [GitHub issue][ghissues] to request addition as a default unit or submit a [pull request][ghpulls]. +You can [add your own custom units](#adding-custom-units) to the workflow. If you think they'd be useful to everyone, please create a corresponding [GitHub issue][ghissues] to request addition as a default unit or submit a [pull request][ghpulls]. ### Supported currencies ### To convert, use the appropriate **abbreviation** for the relevant currencies, e.g. `conv 100 eur gbp`. -You can also view (and search) the list from within Alfred by using the keyword `convinfo` and choosing `View Supported Currencies`. +You can also view (and search) the list from within Alfred by using the keyword `convinfo` and choosing `View All Supported Currencies`. [All supported currencies](./docs/currencies.md). @@ -90,7 +138,7 @@ See [CHANGELOG][changelog] for more information. | Release | Date | |-------------|----------------| -| [3.0][v3.0] | | +| [3.0][v3.0] | 2017-07-16 | | [2.6][v2.6] | 2017-06-15 | | [2.5][v2.5] | 2015-12-11 | | [2.4][v2.4] | 2015-11-28 | @@ -110,7 +158,7 @@ Thanks, copyright, licensing - Exchange rates are downloaded from [Yahoo! Finance][yahoo-finance] and [CryptoCompare][cryptocompare] (for cryptocurrencies). - The [Alfred-Workflow][alfred-workflow] library is used heavily. -All other code/media are released under the [MIT Licence](http://opensource.org/licenses/MIT). +All other code/media are released under the [MIT Licence][mit]. [alfred-workflow]: http://www.deanishe.net/alfred-workflow/ @@ -121,7 +169,7 @@ All other code/media are released under the [MIT Licence](http://opensource.org/ [ghissues]: https://github.com/deanishe/alfred-convert/issues [ghpulls]: https://github.com/deanishe/alfred-convert/pulls [ghreleases]: https://github.com/deanishe/alfred-convert/releases -[packal]: http://www.packal.org/workflow/convert +[mit]: http://opensource.org/licenses/MIT [pintdocs]: http://pint.readthedocs.org/en/latest/index.html [pinthowto]: http://pint.readthedocs.org/en/latest/defining.html [pintrepo]: https://github.com/hgrecco/pint diff --git a/docs/currencies.md b/docs/currencies.md index 7406a0c..8895e24 100644 --- a/docs/currencies.md +++ b/docs/currencies.md @@ -1,186 +1,1414 @@ -# Supported Currencies # +Supported Currencies +==================== + +- [Fiat currencies](#fiat-currencies) +- [Cryptocurrencies](#cryptocurrencies) + +Fiat currencies +--------------- Exchange rates are downloaded from [Yahoo! Finance][yahoo-finance]. -The following currencies are supported by the workflow: +The following fiat currencies are supported by the workflow: + +| Symbol | Name | +| -------- | ----------------------------------- | +| AED | UAE Dirham | +| AFN | Afghani | +| ALL | Lek | +| AMD | Armenian Dram | +| ANG | Netherlands Antillean Guilder | +| AOA | Kwanza | +| ARS | Argentine Peso | +| AUD | Australian Dollar | +| AWG | Aruban Florin | +| AZN | Azerbaijanian Manat | +| BAM | Convertible Mark | +| BBD | Barbados Dollar | +| BDT | Taka | +| BGN | Bulgarian Lev | +| BHD | Bahraini Dinar | +| BIF | Burundi Franc | +| BMD | Bermudian Dollar | +| BND | Brunei Dollar | +| BOB | Boliviano | +| BRL | Brazilian Real | +| BSD | Bahamian Dollar | +| BTN | Ngultrum | +| BWP | Pula | +| BYR | Belarussian Ruble | +| BZD | Belize Dollar | +| CAD | Canadian Dollar | +| CDF | Congolese Franc | +| CHF | Swiss Franc | +| CLF | Unidad de Fomento | +| CLP | Chilean Peso | +| CNY | Yuan Renminbi | +| COP | Colombian Peso | +| CRC | Costa Rican Colon | +| CUC | Peso Convertible | +| CUP | Cuban Peso | +| CVE | Cabo Verde Escudo | +| CZK | Czech Koruna | +| DJF | Djibouti Franc | +| DKK | Danish Krone | +| DOP | Dominican Peso | +| DZD | Algerian Dinar | +| EGP | Egyptian Pound | +| ERN | Nakfa | +| ETB | Ethiopian Birr | +| EUR | Euro | +| FJD | Fiji Dollar | +| FKP | Falkland Islands Pound | +| GBP | Pound Sterling | +| GEL | Lari | +| GHS | Ghana Cedi | +| GIP | Gibraltar Pound | +| GMD | Dalasi | +| GNF | Guinea Franc | +| GTQ | Quetzal | +| GYD | Guyana Dollar | +| HKD | Hong Kong Dollar | +| HNL | Lempira | +| HRK | Kuna | +| HTG | Gourde | +| HUF | Forint | +| IDR | Rupiah | +| ILS | New Israeli Sheqel | +| INR | Indian Rupee | +| IQD | Iraqi Dinar | +| IRR | Iranian Rial | +| ISK | Iceland Krona | +| JMD | Jamaican Dollar | +| JOD | Jordanian Dinar | +| JPY | Yen | +| KES | Kenyan Shilling | +| KGS | Som | +| KHR | Riel | +| KMF | Comoro Franc | +| KPW | North Korean Won | +| KRW | Won | +| KWD | Kuwaiti Dinar | +| KYD | Cayman Islands Dollar | +| KZT | Tenge | +| LAK | Kip | +| LBP | Lebanese Pound | +| LKR | Sri Lanka Rupee | +| LRD | Liberian Dollar | +| LSL | Loti | +| LYD | Libyan Dinar | +| MAD | Moroccan Dirham | +| MDL | Moldovan Leu | +| MGA | Malagasy Ariary | +| MKD | Denar | +| MMK | Kyat | +| MNT | Tugrik | +| MOP | Pataca | +| MRO | Ouguiya | +| MUR | Mauritius Rupee | +| MVR | Rufiyaa | +| MWK | Kwacha | +| MXN | Mexican Peso | +| MXV | Mexican Unidad de Inversion (UDI) | +| MYR | Malaysian Ringgit | +| MZN | Mozambique Metical | +| NAD | Namibia Dollar | +| NGN | Naira | +| NIO | Cordoba Oro | +| NOK | Norwegian Krone | +| NPR | Nepalese Rupee | +| NZD | New Zealand Dollar | +| OMR | Rial Omani | +| PAB | Balboa | +| PEN | Nuevo Sol | +| PGK | Kina | +| PHP | Philippine Peso | +| PKR | Pakistan Rupee | +| PLN | Zloty | +| PYG | Guarani | +| QAR | Qatari Rial | +| RON | Romanian Leu | +| RSD | Serbian Dinar | +| RUB | Russian Ruble | +| RWF | Rwanda Franc | +| SAR | Saudi Riyal | +| SBD | Solomon Islands Dollar | +| SCR | Seychelles Rupee | +| SDG | Sudanese Pound | +| SEK | Swedish Krona | +| SGD | Singapore Dollar | +| SHP | Saint Helena Pound | +| SLL | Leone | +| SOS | Somali Shilling | +| SRD | Surinam Dollar | +| STD | Dobra | +| SVC | El Salvador Colon | +| SYP | Syrian Pound | +| SZL | Lilangeni | +| THB | Baht | +| TJS | Somoni | +| TMT | Turkmenistan New Manat | +| TND | Tunisian Dinar | +| TOP | Pa’anga | +| TRY | Turkish Lira | +| TTD | Trinidad and Tobago Dollar | +| TWD | New Taiwan Dollar | +| TZS | Tanzanian Shilling | +| UAH | Hryvnia | +| UGX | Uganda Shilling | +| USD | US Dollar | +| UYU | Peso Uruguayo | +| UZS | Uzbekistan Sum | +| VEF | Bolivar | +| VND | Dong | +| VUV | Vatu | +| WST | Tala | +| XAF | CFA Franc BEAC | +| XAG | Silver | +| XAU | Gold | +| XCD | East Caribbean Dollar | +| XDR | SDR (Special Drawing Right) | +| XOF | CFA Franc BCEAO | +| XPD | Palladium | +| XPF | CFP Franc | +| XPT | Platinum | +| YER | Yemeni Rial | +| ZAR | Rand | +| ZMW | Zambian Kwacha | +| ZWL | Zimbabwe Dollar | -| Symbol | Name | -|--------|-----------------------------------| -| AED | UAE Dirham | -| AFN | Afghani | -| ALL | Lek | -| AMD | Armenian Dram | -| ANG | Netherlands Antillean Guilder | -| AOA | Kwanza | -| ARS | Argentine Peso | -| AUD | Australian Dollar | -| AWG | Aruban Florin | -| AZN | Azerbaijanian Manat | -| BAM | Convertible Mark | -| BBD | Barbados Dollar | -| BDT | Taka | -| BGN | Bulgarian Lev | -| BHD | Bahraini Dinar | -| BIF | Burundi Franc | -| BMD | Bermudian Dollar | -| BND | Brunei Dollar | -| BOB | Boliviano | -| BRL | Brazilian Real | -| BSD | Bahamian Dollar | -| BTC | Bitcoin | -| BTN | Ngultrum | -| BWP | Pula | -| BYR | Belarussian Ruble | -| BZD | Belize Dollar | -| CAD | Canadian Dollar | -| CDF | Congolese Franc | -| CHF | Swiss Franc | -| CLF | Unidad de Fomento | -| CLP | Chilean Peso | -| CNY | Yuan Renminbi | -| COP | Colombian Peso | -| CRC | Costa Rican Colon | -| CUP | Cuban Peso | -| CVE | Cabo Verde Escudo | -| CZK | Czech Koruna | -| DJF | Djibouti Franc | -| DKK | Danish Krone | -| DOP | Dominican Peso | -| DZD | Algerian Dinar | -| EGP | Egyptian Pound | -| ERN | Nakfa | -| ETB | Ethiopian Birr | -| EUR | Euro | -| FJD | Fiji Dollar | -| FKP | Falkland Islands Pound | -| GBP | Pound Sterling | -| GEL | Lari | -| GHS | Ghana Cedi | -| GIP | Gibraltar Pound | -| GMD | Dalasi | -| GNF | Guinea Franc | -| GTQ | Quetzal | -| GYD | Guyana Dollar | -| HKD | Hong Kong Dollar | -| HNL | Lempira | -| HRK | Kuna | -| HTG | Gourde | -| HUF | Forint | -| IDR | Rupiah | -| ILS | New Israeli Sheqel | -| INR | Indian Rupee | -| IQD | Iraqi Dinar | -| IRR | Iranian Rial | -| ISK | Iceland Krona | -| JMD | Jamaican Dollar | -| JOD | Jordanian Dinar | -| JPY | Yen | -| KES | Kenyan Shilling | -| KGS | Som | -| KHR | Riel | -| KMF | Comoro Franc | -| KPW | North Korean Won | -| KRW | Won | -| KWD | Kuwaiti Dinar | -| KYD | Cayman Islands Dollar | -| KZT | Tenge | -| LAK | Kip | -| LBP | Lebanese Pound | -| LKR | Sri Lanka Rupee | -| LRD | Liberian Dollar | -| LSL | Loti | -| LYD | Libyan Dinar | -| MAD | Moroccan Dirham | -| MDL | Moldovan Leu | -| MGA | Malagasy Ariary | -| MKD | Denar | -| MMK | Kyat | -| MNT | Tugrik | -| MOP | Pataca | -| MRO | Ouguiya | -| MUR | Mauritius Rupee | -| MVR | Rufiyaa | -| MWK | Kwacha | -| MXN | Mexican Peso | -| MXV | Mexican Unidad de Inversion (UDI) | -| MYR | Malaysian Ringgit | -| MZN | Mozambique Metical | -| NAD | Namibia Dollar | -| NGN | Naira | -| NIO | Cordoba Oro | -| NOK | Norwegian Krone | -| NPR | Nepalese Rupee | -| NZD | New Zealand Dollar | -| OMR | Rial Omani | -| PAB | Balboa | -| PEN | Nuevo Sol | -| PGK | Kina | -| PHP | Philippine Peso | -| PKR | Pakistan Rupee | -| PLN | Zloty | -| PYG | Guarani | -| QAR | Qatari Rial | -| RON | Romanian Leu | -| RSD | Serbian Dinar | -| RUB | Russian Ruble | -| RWF | Rwanda Franc | -| SAR | Saudi Riyal | -| SBD | Solomon Islands Dollar | -| SCR | Seychelles Rupee | -| SDG | Sudanese Pound | -| SEK | Swedish Krona | -| SGD | Singapore Dollar | -| SHP | Saint Helena Pound | -| SLL | Leone | -| SOS | Somali Shilling | -| SRD | Surinam Dollar | -| STD | Dobra | -| SVC | El Salvador Colon | -| SYP | Syrian Pound | -| SZL | Lilangeni | -| THB | Baht | -| TJS | Somoni | -| TMT | Turkmenistan New Manat | -| TND | Tunisian Dinar | -| TOP | Pa’anga | -| TRY | Turkish Lira | -| TTD | Trinidad and Tobago Dollar | -| TWD | New Taiwan Dollar | -| TZS | Tanzanian Shilling | -| UAH | Hryvnia | -| UGX | Uganda Shilling | -| USD | US Dollar | -| UYU | Peso Uruguayo | -| UZS | Uzbekistan Sum | -| VEF | Bolivar | -| VND | Dong | -| VUV | Vatu | -| WST | Tala | -| XAF | CFA Franc BEAC | -| XAG | Silver | -| XAU | Gold | -| XCD | East Caribbean Dollar | -| XDR | SDR (Special Drawing Right) | -| XOF | CFA Franc BCEAO | -| XPD | Palladium | -| XPF | CFP Franc | -| XPT | Platinum | -| YER | Yemeni Rial | -| ZAR | Rand | -| ZMW | Zambian Kwacha | -| ZWL | Zimbabwe Dollar | +Cryptocurrencies +---------------- -## Adding new currencies ## +Exchange rates are downloaded from [CryptoCompare.com][cryptocompare]. -If you'd like to add a new currency, please add it to [`currencies_custom.tsv`][currencies_custom] and [submit a pull request][pr]. **This only works for currencies supported by Yahoo! Finance**. +The following cryptocurrencies are supported by the workflow: -Any other currencies will also require adding additional update code to the workflow. +| Symbol | Name | +|----------|--------------------------------------| +| ABY | ArtByte | +| AC | Asia Coin | +| ACES | AcesCoin | +| ACID | AcidCoin | +| ACN | AvonCoin | +| ACOIN | ACoin | +| ACP | Anarchists Prime | +| ADC | AudioCoin | +| ADCN | Asiadigicoin | +| ADN | Aiden | +| ADX | AdEx | +| ADZ | Adzcoin | +| AEC | AcesCoin | +| AEON | AeonCoin | +| AERO | Aero Coin | +| AGS | Aegis | +| AIB | AdvancedInternetBlock | +| AIR | Aircoin | +| ALC | Arab League Coin | +| ALEX | Alexandrite | +| ALF | AlphaCoin | +| ALN | AlienCoin | +| AM | AeroMe | +| AMBER | AmberCoin | +| AMC | AmericanCoin | +| AMIS | AMIS | +| AMP | Synereo | +| AMS | Amsterdam Coin | +| ANAL | AnalCoin | +| ANC | Anoncoin | +| AND | AndromedaCoin | +| ANS | Antshares | +| ANT | Aragon | +| ANTI | Anti Bitcoin | +| APC | AlpaCoin | +| APEX | ApexCoin | +| APT | Aptcoin | +| APX | Apx | +| ARB | Arbit Coin | +| ARCH | ArchCoin | +| ARCO | AquariusCoin | +| ARDR | Ardor | +| ARG | Argentum | +| ARGUS | ArgusCoin | +| ARI | AriCoin | +| ARK | ARK | +| ARM | Armory Coin | +| ARPA | ArpaCoin | +| ASAFE | Allsafe | +| ASN | Ascension Coin | +| AST | Astral | +| ATM | Autumncoin | +| ATMS | Atmos | +| ATOM | Atomic Coin | +| ATX | ArtexCoin | +| AUR | Aurora Coin | +| AV | Avatar Coin | +| AVT | AventCoin | +| AXIOM | Axiom Coin | +| AXR | AXRON | +| B3 | B3 Coin | +| B@ | BankCoin | +| BAC | BitalphaCoin | +| BAN | Babes and Nerds | +| BASH | LuckChain | +| BAT | Basic Attention Token | +| BAY | BitBay | +| BBCC | BaseballCardCoin | +| BBR | Boolberry | +| BCAP | Blockchain Capital | +| BCCOIN | BitConnect Coin | +| BCF | BitcoinFast | +| BCN | ByteCoin | +| BCR | BitCredit | +| BCX | BattleCoin | +| BCY | BitCrystals | +| BELA | BelaCoin | +| BEN | Benjamins | +| BENJI | BenjiRolls | +| BERN | BERNcash | +| BEST | BestChain | +| BET | BetaCoin | +| BFX | BitFinex Tokens | +| BHC | BighanCoin | +| BIC | Bikercoins | +| BIGUP | BigUp | +| BIOB | BioBar | +| BIOS | BiosCrypto | +| BIP | BipCoin | +| BIT16 | 16BitCoin | +| BITB | BitBean | +| BITCNY | bitCNY | +| BITOK | BitOKX | +| BITS | BitstarCoin | +| BITUSD | bitUSD | +| BITZ | Bitz Coin | +| BLAZR | BlazerCoin | +| BLC | BlakeCoin | +| BLITZ | BlitzCoin | +| BLK | BlackCoin | +| BLOCK | BlockNet | +| BLRY | BillaryCoin | +| BLU | BlueCoin | +| BM | BitMoon | +| BNB | Boats and Bitches | +| BNT | Bancor Network Token | +| BNX | BnrtxCoin | +| BOB | Bob Coin | +| BOLI | BolivarCoin | +| BOMB | BombCoin | +| BON | BonesCoin | +| BOOM | BOOM Coin | +| BOS | BOScoin | +| BOSON | BosonCoin | +| BOSS | BitBoss | +| BOST | BoostCoin | +| BQC | BQCoin | +| BQX | Bitquence | +| BRAIN | BrainCoin | +| BRDD | BeardDollars | +| BRK | BreakoutCoin | +| BRONZ | BitBronze | +| BS | BlackShadowCoin | +| BSC | BowsCoin | +| BSD | BitSend | +| BST | BitStone | +| BSTAR | Blackstar | +| BSTK | BattleStake | +| BSTY | GlobalBoost | +| BTA | Bata | +| BTB | BitBar | +| BTC | Bitcoin | +| BTCD | BitcoinDark | +| BTCR | BitCurrency | +| BTCRY | BitCrystal | +| BTCS | Bitcoin Scrypt | +| BTD | Bitcloud | +| BTE | ByteCoin | +| BTG | BitGem | +| BTLC | BitLuckCoin | +| BTM | BitMark | +| BTMI | BitMiles | +| BTQ | BitQuark | +| BTS | Bitshares | +| BTTF | Coin to the Future | +| BTX | BitcoinTX | +| BTZ | BitzCoin | +| BUCKS | SwagBucks | +| BUK | CryptoBuk | +| BURST | BurstCoin | +| BUZZ | BuzzCoin | +| BVC | BeaverCoin | +| BXC | Bitcedi | +| BXT | BitTokens | +| BYC | ByteCent | +| C2 | Coin.2 | +| CAB | CabbageUnit | +| CACH | Cachecoin | +| CAIX | CAIx | +| CALC | CaliphCoin | +| CAM | Camcoin | +| CANN | CannabisCoin | +| CAP | BottleCaps | +| CARBON | Carboncoin | +| CASH | CashCoin | +| CAT | Catcoin | +| CBD | CBD Crystals | +| CBX | CryptoBullion | +| CC | CyberCoin | +| CCN | CannaCoin | +| CCRB | CryptoCarbon | +| CCX | CoolDarkCoin | +| CDN | Canada eCoin | +| CELL | SolarFarm | +| CESC | Crypto Escudo | +| CETI | CETUS Coin | +| CF | Californium | +| CFC | CoffeeCoin | +| CFI | Cofound.it | +| CFT | CryptoForecast | +| CGA | Cryptographic Anomaly | +| CHA | Charity Coin | +| CHAO | 23 Skidoo | +| CHASH | CleverHash | +| CHAT | ChatCoin | +| CHC | ChainCoin | +| CHESS | ChessCoin | +| CHIEF | TheChiefCoin | +| CHILD | ChildCoin | +| CHIP | Chip | +| CHOOF | ChoofCoin | +| CIN | CinderCoin | +| CINNI | CINNICOIN | +| CIR | CircuitCoin | +| CIRC | CryptoCircuits | +| CJ | CryptoJacks | +| CJC | CryptoJournal | +| CKC | Clockcoin | +| CLAM | CLAMS | +| CLICK | Clickcoin | +| CLINT | Clinton | +| CLOAK | CloakCoin | +| CLR | CopperLark | +| CLUB | ClubCoin | +| CLUD | CludCoin | +| CLV | CleverCoin | +| CMC | CosmosCoin | +| CMT | CometCoin | +| CNC | ChinaCoin | +| CNL | ConcealCoin | +| CNMT | Coinomat | +| CNO | Coino | +| CNT | Centurion | +| COC | Community Coin | +| COIN | Coin | +| COMM | Community Coin | +| CON | Paycon | +| COOL | CoolCoin | +| CORAL | CoralPay | +| COV | CovenCoin | +| COVAL | Circuits of Value | +| COX | CobraCoin | +| CPC | CapriCoin | +| CQST | ConquestCoin | +| CRAB | CrabCoin | +| CRACK | CrackCoin | +| CRAFT | Craftcoin | +| CRAIG | CraigsCoin | +| CRAVE | CraveCoin | +| CRBIT | Creditbit | +| CRC | CraftCoin | +| CRE | Credits | +| CREA | CreativeChain | +| CREVA | Creva Coin | +| CRNK | CrankCoin | +| CRPS | CryptoPennies | +| CRW | Crown Coin | +| CRX | ChronosCoin | +| CRYPT | CryptCoin | +| CS | CryptoSpots | +| CSC | CasinoCoin | +| CSH | CashOut | +| CSMIC | Cosmic | +| CTC | CarterCoin | +| CTIC | Coinmatic | +| CTO | Crypto | +| CUBE | DigiCube | +| CURE | Curecoin | +| CV2 | ColossusCoin2.0 | +| CWXT | CryptoWorldXToken | +| CXC | CheckCoin | +| CXT | Coinonat | +| CYC | ConSpiracy Coin | +| CYG | Cygnus | +| CYP | CypherPunkCoin | +| CYT | Cryptokenz | +| DANK | DarkKush | +| DAR | Darcrus | +| DARK | Dark | +| DASH | DigitalCash | +| DB | DarkBit | +| DBG | Digital Bullion Gold | +| DBIC | DubaiCoin | +| DBIX | DubaiCoin | +| DBTC | DebitCoin | +| DCC | DarkCrave | +| DCK | DickCoin | +| DCR | Decred | +| DCRE | DeltaCredits | +| DCT | Decent | +| DCY | Dinastycoin | +| DDF | Digital Developers Fund | +| DEA | Degas Coin | +| DEM | eMark | +| DENT | Dent | +| DES | Destiny | +| DETH | DarkEther | +| DEUR | DigiEuro | +| DGB | DigiByte | +| DGC | DigiCoin | +| DGD | Digix DAO | +| DGDC | DarkGold | +| DGMS | Digigems | +| DGORE | DogeGoreCoin | +| DICE | Etheroll | +| DIEM | CarpeDiemCoin | +| DIGS | Diggits | +| DIME | DimeCoin | +| DISK | Dark Lisk | +| DKC | DarkKnightCoin | +| DLC | DollarCoin | +| DLISK | Dlisk | +| DMD | Diamond | +| DNET | Darknet | +| DOGE | Dogecoin | +| DOGED | DogeCoinDark | +| DOGETH | EtherDoge | +| DOPE | DopeCoin | +| DOT | Dotcoin | +| DOV | DonationCoin | +| DP | DigitalPrice | +| DPAY | DelightPay | +| DRA | DraculaCoin | +| DRACO | DT Token | +| DRKC | DarkCash | +| DRKT | DarkTron | +| DRM8 | Dream8Coin | +| DROP | FaucetCoin | +| DRZ | Droidz | +| DSB | DarkShibe | +| DSH | Dashcoin | +| DT | DarkToken | +| DTB | Databits | +| DTC | DayTrader Coin | +| DUB | DubCoin | +| DUCK | DuckDuckCoin | +| DUO | ParallelCoin | +| DUX | DuxCoin | +| DVC | DevCoin | +| DYN | Dynamic | +| EA | EagleCoin | +| EAC | EarthCoin | +| EAGS | EagsCoin | +| EB3 | EB3coin | +| EBS | EbolaShare | +| EC | Eclipse | +| ECO | ECOcoin | +| ECOB | EcoBit | +| EDC | EducoinV | +| EDG | Edgeless | +| EDGE | EdgeCoin | +| EDR | E-Dinar Coin | +| EDRC | EDRCoin | +| EFL | E-Gulden | +| EGC | EverGreenCoin | +| EGG | EggCoin | +| EGO | EGOcoin | +| EKN | Elektron | +| EKO | EkoCoin | +| ELC | Elacoin | +| ELE | Elementrem | +| ELS | Elysium | +| EMB | EmberCoin | +| EMC | Emercoin | +| EMC2 | Einsteinium | +| EMD | Emerald | +| EMPC | EmporiumCoin | +| ENE | EneCoin | +| ENRG | EnergyCoin | +| ENT | Eternity | +| ENTER | EnterCoin (ENTER) | +| EOC | EveryonesCoin | +| EOS | EOS | +| EPY | Empyrean | +| EQM | Equilibrium Coin | +| EQT | EquiTrader | +| EQUAL | EqualCoin | +| ERC | EuropeCoin | +| ERR | ErrorCoin | +| ERY | Eryllium | +| ESP | Espers | +| ETC | Ethereum Classic | +| ETH | Ethereum | +| ETHS | EthereumScrypt | +| EUC | Eurocoin | +| EVENT | Event Token | +| EVIL | EvilCoin | +| EXB | ExaByte (EXB) | +| EXCL | Exclusive Coin | +| EXE | ExeCoin | +| EXIT | ExitCoin | +| EXP | Expanse | +| EZC | EZCoin | +| F16 | F16Coin | +| FAIR | FairCoin | +| FAME | FameCoin | +| FAZZ | FazzCoin | +| FC2 | Fuel2Coin | +| FCN | FantomCoin | +| FCS | CryptoFocus | +| FCT | Factoids | +| FFC | FireflyCoin | +| FGZ | Free Game Zone | +| FIBRE | FIBRE | +| FIND | FindCoin | +| FIRE | FireCoin | +| FIRST | FirstCoin | +| FIST | FistBump | +| FIT | Fitcoin | +| FJC | FujiCoin | +| FLDC | Folding Coin | +| FLO | FlorinCoin | +| FLT | FlutterCoin | +| FLVR | FlavorCoin | +| FLX | Flash | +| FLY | FlyCoin | +| FONZ | FonzieCoin | +| FOREX | ForexCoin | +| FRAC | FractalCoin | +| FRC | FireRoosterCoin | +| FRE | FreeCoin | +| FRK | Franko | +| FRN | Francs | +| FRST | FirstCoin | +| FRWC | Frankywillcoin | +| FSC2 | FriendshipCoin | +| FSN | Fusion | +| FST | FastCoin | +| FTC | FeatherCoin | +| FTP | FuturePoints | +| FUN | FunFair | +| FUNC | FunCoin | +| FUTC | FutCoin | +| FUZZ | Fuzzballs | +| FX | FCoin | +| FYN | FundYourselfNow | +| GAIA | GAIA Platform | +| GAKH | GAKHcoin | +| GAM | Gambit coin | +| GAME | Gamecredits | +| GAP | Gapcoin | +| GAY | GayCoin | +| GB | GoldBlocks | +| GBIT | GravityBit | +| GBRC | GBR Coin | +| GBT | GameBetCoin | +| GBYTE | Byteball | +| GCC | GuccioneCoin | +| GCR | Global Currency Reserve | +| GDC | GrandCoin | +| GEMZ | Gemz Social | +| GEN | Genstake | +| GEO | GeoCoin | +| GHC | GhostCoin | +| GHOUL | Ghoul Coin | +| GHS | Giga Hash | +| GIFT | GiftNet | +| GIG | GigCoin | +| GIVE | GiveCoin | +| GIZ | GIZMOcoin | +| GLC | GlobalCoin | +| GLD | GoldCoin | +| GLOBE | Global | +| GLX | GalaxyCoin | +| GLYPH | GlyphCoin | +| GMC | Gridmaster | +| GML | GameLeagueCoin | +| GMX | Goldmaxcoin | +| GNJ | GanjaCoin V2 | +| GNO | Gnosis | +| GNT | Golem Network Token | +| GOAT | Goat | +| GOLOS | Golos | +| GOON | Goonies | +| GOT | Giotto Coin | +| GOTX | GothicCoin | +| GP | GoldPieces | +| GPL | Gold Pressed Latinum | +| GPU | GPU Coin | +| GRAM | Gram Coin | +| GRAV | Graviton | +| GRC | GridCoin | +| GRE | GreenCoin | +| GREXIT | GrexitCoin | +| GRID | GridPay | +| GRM | GridMaster | +| GROW | GrownCoin | +| GRS | Groestlcoin | +| GRT | Grantcoin | +| GRW | GrowthCoin | +| GSM | GSM Coin | +| GSX | GlowShares | +| GSY | GenesysCoin | +| GUE | GuerillaCoin | +| GUP | Guppy | +| HAL | Halcyon | +| HALLO | Halloween Coin | +| HAMS | HamsterCoin | +| HAZE | HazeCoin | +| HBN | HoboNickels | +| HCC | HappyCreatorCoin | +| HEAT | Heat Ledger | +| HEDG | Hedgecoin | +| HEEL | HeelCoin | +| HILL | President Clinton | +| HIRE | BitHIRE | +| HKG | Hacker Gold | +| HMP | HempCoin | +| HMQ | Humaniq | +| HNC | Hellenic Coin | +| HODL | HOdlcoin | +| HPC | HappyCoin | +| HRB | Harbour DAO | +| HSP | Horse Power | +| HTC | Hitcoin | +| HTML5 | HTML Coin | +| HUC | HunterCoin | +| HUGE | BigCoin | +| HUSH | Hush | +| HVC | HeavyCoin | +| HVCO | High Voltage Coin | +| HXX | HexxCoin | +| HYP | Hyperstake | +| HYPER | HyperCoin | +| HZ | Horizon | +| HZT | HazMatCoin | +| I0C | I0coin | +| IBANK | iBankCoin | +| ICASH | ICASH | +| ICB | IceBergCoin | +| ICN | Iconomi | +| ICOB | Icobid | +| ICON | Iconic | +| IEC | IvugeoEvolutionCoin | +| IFC | Infinite Coin | +| IFLT | InflationCoin | +| ILC | ILCoin | +| IMPCH | Impeach | +| IMPS | Impulse Coin | +| IMS | Independent Money System | +| IN | InCoin | +| INC | Incrementum | +| INCNT | Incent | +| INCP | InceptionCoin | +| INFX | Influxcoin | +| INPAY | InPay | +| INSANE | InsaneCoin | +| INSN | Insane Coin | +| INV | Invictus | +| IOC | IOCoin | +| ION | Ionomy | +| IOP | Internet of People | +| IOT | IOTA | +| IOU | IOU1 | +| ISL | IslaCoin | +| IVZ | InvisibleCoin | +| IW | iWallet | +| IXC | IXcoin | +| IXT | InsureX | +| J | JoinCoin | +| JANE | JaneCoin | +| JBS | JumBucks Coin | +| JIF | JiffyCoin | +| JIO | JIO Token | +| JKC | JunkCoin | +| JNS | Janus | +| JOBS | JobsCoin | +| JOK | JokerCoin | +| JPC | JackPotCoin | +| JUDGE | JudgeCoin | +| JWL | Jewels | +| KARM | Karmacoin | +| KAT | KATZcoin | +| KAYI | Kayı | +| KC | Kernalcoin | +| KDC | Klondike Coin | +| KED | Klingon Empire Darsek | +| KEY | KeyCoin | +| KGC | KrugerCoin | +| KLC | KiloCoin | +| KMD | Komodo | +| KNC | Khancoin | +| KOBO | KoboCoin | +| KORE | KoreCoin | +| KR | Krypton | +| KRAK | Kraken | +| KRB | Karbowanec | +| KRC | KRCoin | +| KTK | KryptCoin | +| KUBO | KubosCoin | +| KURT | Kurrent | +| KUSH | KushCoin | +| LAB | CoinWorksCoin | +| LANA | LanaCoin | +| LAZ | Lazarus | +| LBC | LBRY Credits | +| LC | Lutetium Coin | +| LDOGE | LiteDoge | +| LEA | LeaCoin | +| LEMON | LemonCoin | +| LENIN | LeninCoin | +| LEO | LEOcoin | +| LEPEN | LePenCoin | +| LFC | BigLifeCoin | +| LGBTQ | LGBTQoin | +| LGD | Legends Cryptocurrency | +| LIMX | LimeCoinX | +| LIR | Let it Ride | +| LIV | LiviaCoin | +| LK7 | Lucky7Coin | +| LKY | LuckyCoin | +| LMC | LomoCoin | +| LOC | Loco | +| LOG | Wood Coin | +| LOOK | LookCoin | +| LQD | Liquid | +| LSD | LightSpeedCoin | +| LSK | Lisk | +| LTB | Litebar | +| LTBC | LTBCoin | +| LTC | Litecoin | +| LTCD | LitecoinDark | +| LTCR | LiteCreed | +| LTCX | LitecoinX | +| LTD | Limited Coin | +| LTH | Lathaan | +| LTS | Litestar Coin | +| LUCKY | LuckyBlocks (LUCKY) | +| LUN | Lunyr | +| LUX | BitLux | +| LVG | Leverage Coin | +| LXC | LibrexCoin | +| LYB | LyraBar | +| LYC | LycanCoin | +| M1 | SupplyShock | +| MAC | MachineCoin | +| MAD | SatoshiMadness | +| MAID | MaidSafe Coin | +| MAPC | MapCoin | +| MAR | MarijuanaCoin | +| MARS | MarsCoin | +| MARV | Marvelous | +| MARX | MarxCoin | +| MARYJ | MaryJane Coin | +| MAT | Manet Coin | +| MAX | MaxCoin | +| MBIT | Mbitbooks | +| MCAP | MCAP | +| MCAR | MasterCar | +| MCN | MonetaVerde | +| MCO | Monaco | +| MCRN | MacronCoin | +| MDC | MedicCoin | +| MDT | Midnight | +| MEC | MegaCoin | +| MED | MediterraneanCoin | +| MEGA | MegaFlash | +| MEME | Pepe | +| MER | Mercury | +| METAL | MetalCoin | +| MG | Mind Gene | +| MGO | MobileGo | +| MI | XiaoMiCoin | +| MIL | Milllionaire Coin | +| MILO | MiloCoin | +| MIN | Minerals Coin | +| MINE | Instamine Nuggets | +| MINT | MintCoin | +| MIS | MIScoin | +| MKR | Maker | +| MLITE | MeLite | +| MLN | Melon | +| MM | MasterMint | +| MMC | MemoryCoin | +| MMNXT | MMNXT | +| MMXIV | MaieutiCoin | +| MMXVI | MMXVI | +| MN | Cryptsy Mining Contract | +| MNC | MinCoin | +| MND | MindCoin | +| MNE | Minereum | +| MNM | Mineum | +| MOIN | MoinCoin | +| MOJO | Mojocoin | +| MONA | MonaCoin | +| MONETA | Moneta | +| MONEY | MoneyCoin | +| MOON | MoonCoin | +| MOOND | Dark Moon | +| MOTO | Motocoin | +| MPRO | MediumProject | +| MRP | MorpheusCoin | +| MRS | MarsCoin | +| MRSA | MrsaCoin | +| MRT | MinersReward | +| MRY | MemoryCoin | +| MSC | MasterCoin | +| MST | MustangCoin | +| MT | Mycelium Token | +| MTL | Metal | +| MTR | MasterTraderCoin | +| MUDRA | MudraCoin | +| MUE | MonetaryUnit | +| MUSIC | Musiccoin | +| MUU | MilkCoin | +| MWC | MultiWallet Coin | +| MXT | MartexCoin | +| MYB | MyBit | +| MYC | MayaCoin | +| MYST | MysteryCoin | +| MZC | MazaCoin | +| N7 | Number7 | +| NAN | NanoToken | +| NANAS | BananaBits | +| NAS2 | Nas2Coin | +| NAUT | Nautilus Coin | +| NAV | NavCoin | +| NBIT | NetBit | +| NBL | Nybble | +| NBT | NuBits | +| NDOGE | NinjaDoge | +| NEBU | Nebuchadnezzar | +| NEC | NeoCoin | +| NEF | NefariousCoin | +| NEOS | NeosCoin | +| NET | NetCoin | +| NETC | NetworkCoin | +| NETKO | Netko | +| NEU | NeuCoin | +| NEVA | NevaCoin | +| NIC | NewInvestCoin | +| NICE | NiceCoin | +| NKA | IncaKoin | +| NKC | Nukecoinz | +| NKT | NakomotoDark | +| NLC | NoLimitCoin | +| NLG | Gulden | +| NMB | Nimbus Coin | +| NMC | NameCoin | +| NMR | Numerai | +| NOBL | NobleCoin | +| NODE | Node | +| NOO | Noocoin | +| NOTE | Dnotes | +| NPC | NPCcoin | +| NRB | NoirBits | +| NRC | Neurocoin | +| NRS | NoirShares | +| NSR | NuShares | +| NTC | NineElevenTruthCoin | +| NTCC | NeptuneClassic | +| NTRN | Neutron | +| NUBIS | NubisCoin | +| NUKE | NukeCoin | +| NUM | NumbersCoin | +| NVC | NovaCoin | +| NXC | Nexium | +| NXE | NXEcoin | +| NXS | Nexus | +| NXT | Nxt | +| NXTI | NXTI | +| NXTTY | NXTTY | +| NYAN | NyanCoin | +| NZC | NewZealandCoin | +| OAX | OpenANX | +| OBITS | Obits Coin | +| OBS | Obscurebay | +| OC | OrangeCoin | +| OCTO | OctoCoin | +| ODNT | Old Dogs New Tricks | +| OK | OKCash | +| OLDSF | OldSafeCoin | +| OLYMP | OlympCoin | +| OMA | OmegaCoin | +| OMC | OmniCron | +| OMNI | Omni | +| OPAL | OpalCoin | +| OPES | Opes | +| OPTION | OptionCoin | +| ORB | Orbitcoin | +| ORLY | OrlyCoin | +| ORO | OroCoin | +| OS76 | OsmiumCoin | +| OSC | OpenSourceCoin | +| PAC | PacCoin | +| PAK | Pakcoin | +| PARA | ParanoiaCoin | +| PASC | Pascal Coin | +| PASL | Pascal Lite | +| PAY | TenX | +| PAYP | PayPeer | +| PBC | PabyosiCoin | +| PCM | Procom | +| PCS | Pabyosi Coin | +| PDC | Project Decorum | +| PEC | PeaceCoin | +| PEN | PenCoin | +| PEPECASH | Pepe Cash | +| PEX | PosEx | +| PHR | Phreak | +| PHS | PhilosophersStone | +| PIE | Persistent Information Exchange | +| PIGGY | Piggy Coin | +| PING | CryptoPing | +| PINK | PinkCoin | +| PINKX | PantherCoin | +| PIO | Pioneershares | +| PIVX | Private Instant Verified Transaction | +| PIZZA | PizzaCoin | +| PKB | ParkByte | +| PLANET | PlanetCoin | +| PLBT | Polybius | +| PLNC | PLNCoin | +| PLU | Pluton | +| PNC | PlatiniumCoin | +| PND | PandaCoin | +| PNK | SteamPunk | +| POINTS | Cryptsy Points | +| POLY | PolyBit | +| POST | PostCoin | +| POSW | PoSWallet | +| POT | PotCoin | +| PPC | PeerCoin | +| PPT | Populous | +| PPY | Peerplays | +| PRC | ProsperCoin | +| PRE | Premium | +| PRES | President Trump | +| PRIME | PrimeChain | +| PRM | PrismChain | +| PROC | ProCurrency | +| PRX | Printerium | +| PSB | PesoBit | +| PSEUD | PseudoCash | +| PSI | PSIcoin | +| PSY | Psilocybin | +| PTA | PentaCoin | +| PTC | PesetaCoin | +| PTOY | Patientory | +| PTS | Protoshares | +| PULSE | Pulse | +| PUPA | PupaCoin | +| PUT | PutinCoin | +| PWR | PowerCoin | +| PX | PXcoin | +| PXC | PhoenixCoin | +| PXI | Prime-X1 | +| PXL | Phalanx | +| PYC | PayCoin | +| QAU | Quantum | +| QBC | Quebecoin | +| QBK | QuBuck Coin | +| QBT | Cubits | +| QCN | Quazar Coin | +| QORA | QoraCoin | +| QRK | QuarkCoin | +| QRL | Quantum Resistant Ledger | +| QSLV | Quicksilver coin | +| QTL | Quatloo | +| QTUM | QTUM | +| QTZ | Quartz | +| QWARK | Qwark | +| RADI | RadicalCoin | +| RADS | Radium | +| RAIN | Condensate | +| RATIO | Ratio | +| RBIES | Rubies | +| RBIT | ReturnBit | +| RBR | Ribbit Rewards | +| RBT | Rimbit | +| RBX | RiptoBuX | +| RBY | RubyCoin | +| RC | Russiacoin | +| RCN | RCoin | +| RCX | RedCrowCoin | +| RDD | ReddCoin | +| RDN | RadonPay | +| RED | Redcoin | +| REE | ReeCoin | +| REP | Augur | +| REV | Revenu | +| RIC | Riecoin | +| RICE | RiceCoin | +| RIDE | Ride My Car | +| RING | RingCoin | +| RIPO | RipOffCoin | +| RISE | Rise | +| RLC | iEx.ec | +| RMS | Resumeo Shares | +| RNC | ReturnCoin | +| RNS | RenosCoin | +| ROOT | RootCoin | +| ROS | ROS Coin | +| ROUND | RoundCoin | +| ROYAL | RoyalCoin | +| RPC | RonPaulCoin | +| RRT | Recovery Right Tokens | +| RT2 | RotoCoin | +| RUBIT | Rublebit | +| RUST | RustCoin | +| RYC | RoyalCoin | +| RYCN | RoyalCoin 2.0 | +| RZR | RazorCoin | +| S8C | S88 Coin | +| SAK | SharkCoin | +| SAN | Santiment | +| SANDG | Save and Gain | +| SAR | SARCoin | +| SAT2 | Saturn2Coin | +| SBC | StableCoin | +| SBD | Steem Backed Dollars | +| SC | Siacoin | +| SCASH | SpaceCash | +| SCN | Swiscoin | +| SCOT | Scotcoin | +| SCRPT | ScryptCoin | +| SCRT | SecretCoin | +| SCT | ScryptToken | +| SDC | ShadowCash | +| SDP | SydPakCoin | +| SEC | SafeExchangeCoin | +| SEEDS | SeedShares | +| SEL | SelenCoin | +| SEN | Sentaro | +| SEQ | Sequence | +| SFC | Solarflarecoin | +| SFE | Safecoin | +| SFR | SaffronCoin | +| SH | Shilling | +| SHADE | ShadeCoin | +| SHIFT | Shift | +| SHLD | ShieldCoin | +| SHORTY | ShortyCoin | +| SIB | SibCoin | +| SIGU | Singular | +| SILK | SilkCoin | +| SJCX | StorjCoin | +| SKB | SkullBuzz | +| SKY | Skycoin | +| SLG | SterlingCoin | +| SLING | Sling Coin | +| SLM | SlimCoin | +| SLR | SolarCoin | +| SLS | SaluS | +| SMAC | Social Media Coin | +| SMC | SmartCoin | +| SMF | SmurfCoin | +| SMLY | SmileyCoin | +| SMSR | Samsara Coin | +| SNC | SunContract | +| SNGLS | SingularDTV | +| SNM | SONM | +| SNRG | Synergy | +| SNT | Status Network Token | +| SOIL | SoilCoin | +| SOLE | SoleCoin | +| SONG | Song Coin | +| SOON | SoonCoin | +| SOUL | SoulCoin | +| SP | Sex Pistols | +| SPA | SpainCoin | +| SPACE | SpaceCoin | +| SPC | SpinCoin | +| SPEC | SpecCoin | +| SPHR | Sphere Coin | +| SPKTR | Ghost Coin | +| SPM | Supreme | +| SPORT | SportsCoin | +| SPOTS | Spots | +| SPR | Spreadcoin | +| SPRTS | Sprouts | +| SPT | Spots | +| SPX | Specie | +| SQL | Squall Coin | +| SRC | SecureCoin | +| SSD | Sonic Screw Driver Coin | +| SSTC | SunShotCoin | +| SSV | SSVCoin | +| STA | Stakers | +| STALIN | StalinCoin | +| STAR | StarCoin | +| START | StartCoin | +| STEEM | Steem | +| STEPS | Steps | +| STHR | Stakerush | +| STO | Save The Ocean | +| STR* | StarCoin | +| STRAT | Stratis | +| STS | STRESScoin | +| STV | Sativa Coin | +| SUB | Subscriptio | +| SUP | Supcoin | +| SUPER | SuperCoin | +| SUR | Suretly | +| SWARM | SwarmCoin | +| SWEET | SweetStake | +| SWIFT | BitSwift | +| SWING | SwingCoin | +| SWT | Swarm City Token | +| SXC | SexCoin | +| SYNC | SyncCoin | +| SYNX | Syndicate | +| SYS | SysCoin | +| TAAS | Token as a Service | +| TAB | MollyCoin | +| TAG | TagCoin | +| TAGR | Think And Get Rich Coin | +| TAJ | TajCoin | +| TAK | TakCoin | +| TAM | TamaGucci | +| TAP | TappingCoin | +| TBCX | TrashBurn | +| TCR | Thecreed | +| TDFB | TDFB | +| TEAM | TeamUP | +| TEC | TeCoin | +| TECH | TechCoin | +| TEK | TekCoin | +| TELL | Tellurion | +| TENNET | Tennet | +| TES | TeslaCoin | +| TESLA | TeslaCoilCoin | +| TFL | True Flip Lottery | +| TGC | TigerCoin | +| THC | The Hempcoin | +| THS | TechShares | +| TIA | Tianhe | +| TIC | TrueInvestmentCoin | +| TIME | Time | +| TIT | TitCoin | +| TIX | Blocktix | +| TKN | TokenCard | +| TKS | Tokes | +| TMC | TimesCoin | +| TODAY | TodayCoin | +| TOR | TorCoin | +| TOT | TotCoin | +| TPAY | TrollPlay | +| TPG | Troll Payment | +| TRA | Tetra | +| TRC | TerraCoin | +| TRI | Triangles Coin | +| TRICK | TrickyCoin | +| TRIG | Trigger | +| TRK | TruckCoin | +| TRON | Positron | +| TRST | TrustCoin | +| TRUMP | TrumpCoin | +| TRUST | TrustPlus | +| TSE | TattooCoin | +| TTC | TittieCoin | +| TUR | Turron | +| TWIST | TwisterCoin | +| TWLV | Twelve Coin | +| TX | Transfer | +| U | Ucoin | +| UBIQ | Ubiqoin | +| UBQ | Ubiq | +| UFO | UFO Coin | +| UIS | Unitus | +| ULTC | Umbrella | +| UNAT | Unattanium | +| UNB | UnbreakableCoin | +| UNC | UnCoin | +| UNF | Unfed Coin | +| UNI | Universe | +| UNIQ | Uniqredit | +| UNIT | Universal Currency | +| UNITS | GameUnits | +| UNITY | SuperNET | +| UNO | Unobtanium | +| UR | UR | +| URO | UroCoin | +| USC | Ultimate Secure Cash | +| USDE | UnitaryStatus Dollar | +| USDT | Tether | +| UTC | UltraCoin | +| UTH | Uther | +| UTIL | Utility Coin | +| VAPOR | Vaporcoin | +| VDO | VidioCoin | +| VEC2 | VectorCoin 2.0 | +| VEG | BitVegan | +| VERI | Veritaseum | +| VERSA | Versa Token | +| VIA | ViaCoin | +| VIDZ | PureVidz | +| VIOR | ViorCoin | +| VIP | VIP Tokens | +| VIRAL | Viral Coin | +| VISIO | Visio | +| VLT | Veltor | +| VLTC | VaultCoin | +| VMC | VirtualMining Coin | +| VOLT | BitVolt | +| VOOT | VootCoin | +| VOX | Voxels | +| VOYA | Voyacoin | +| VPRC | VapersCoin | +| VRC | VeriCoin | +| VRM | Verium | +| VRS | Veros | +| VSL | vSlice | +| VTA | VirtaCoin | +| VTC | VertCoin | +| VTR | Vtorrent | +| VTX | Vertex | +| VTY | Victoriouscoin | +| VUC | Virta Unique Coin | +| WARP | WarpCoin | +| WASH | WashingtonCoin | +| WAVES | Waves | +| WAY | WayCoin | +| WBB | Wild Beast Coin | +| WBTC | wBTC | +| WC | WhiteCoin | +| WCT | Waves Community Token | +| WDC | WorldCoin | +| WEALTH | WealthCoin | +| WEX | Wexcoin | +| WGC | World Gold Coin | +| WGO | WavesGO | +| WGR | Wagerr | +| WINE | WineCoin | +| WINGS | Wings DAO | +| WISC | WisdomCoin | +| WMC | WMCoin | +| WOLF | Insanity Coin | +| WOP | WorldPay | +| WRC | WarCoin | +| WSX | WeAreSatoshi | +| WTT | Giga Watt | +| X2 | X2Coin | +| XAI | SapienceCoin | +| XAU | XauCoin | +| XAUR | Xaurum | +| XBC | BitcoinPlus | +| XBOT | SocialXbotCoin | +| XBS | Bitstake | +| XBTS | Beats | +| XBY | XtraBYtes | +| XC | X11 Coin | +| XCASH | Xcash | +| XCE | Cerium | +| XCI | Cannabis Industry Coin | +| XCN | Cryptonite | +| XCO | XCoin | +| XCP | CounterParty | +| XCR | Crypti | +| XCRE | Creatio | +| XCT | C-Bits | +| XDB | DragonSphere | +| XDE2 | XDE II | +| XDN | DigitalNote | +| XDP | DogeParty | +| XDQ | Dirac Coin | +| XEL | Elastic | +| XEM | NEM | +| XEN | XenixCoin | +| XFC | Forever Coin | +| XG | XG Sports | +| XGB | GoldenBird | +| XGR | GoldReserve | +| XHI | HiCoin | +| XID | International Diamond Coin | +| XJO | JouleCoin | +| XLB | LibertyCoin | +| XLM | Stellar | +| XLR | Solaris | +| XMG | Coin Magi | +| XMR | Monero | +| XMS | Megastake | +| XMY | MyriadCoin | +| XNA | DeOxyRibose | +| XNC | Numismatic Collections | +| XNG | Enigma | +| XNX | XanaxCoin | +| XPB | Pebble Coin | +| XPD | PetroDollar | +| XPH | PharmaCoin | +| XPM | PrimeCoin | +| XPO | Opair | +| XPOKE | PokeChain | +| XPRO | ProCoin | +| XPS | PoisonIvyCoin | +| XPY | PayCoin | +| XQN | Quotient | +| XRA | Ratecoin | +| XRB | RaiBlocks | +| XRE | RevolverCoin | +| XRL | Rialto.AI | +| XRP | Ripple | +| XSEED | BitSeeds | +| XSI | Stability Shares | +| XSP | PoolStamp | +| XSPEC | Spectre | +| XST | StealthCoin | +| XT | ExtremeCoin | +| XTC | TileCoin | +| XTZ | Tezos | +| XUP | UPcoin | +| XVC | Vcash | +| XVE | The Vegan Initiative | +| XVG | Verge | +| XVP | VirtacoinPlus | +| XVS | Vsync | +| XWC | WhiteCoin | +| XWT | World Trade Funds | +| XXX | XXXCoin | +| XZC | ZCoin | +| YAC | YAcCoin | +| YAY | YAYcoin | +| YBC | YbCoin | +| YES | YesCoin | +| YMC | YamahaCoin | +| YOC | YoCoin | +| YOVI | YobitVirtualCoin | +| ZBC | Zilbercoin | +| ZCC | ZCC Coin | +| ZCL | ZClassic | +| ZEC | ZCash | +| ZECD | ZCashDarkCoin | +| ZED | ZedCoins | +| ZEIT | ZeitCoin | +| ZEN | ZenCash | +| ZENI | Zennies | +| ZER | Zero | +| ZET | ZetaCoin | +| ZET2 | Zeta2Coin | +| ZLQ | ZLiteQubit | +| ZNE | ZoneCoin | +| ZNY | BitZeny | +| ZOI | Zoin | +| ZOOM | ZoomCoin | +| ZRC | ZrCoin | +| ZSE | ZSEcoin | +| ZUR | Zurcoin | +| ZXT | Zcrypt | +| ZYD | ZayedCoin | -Support for other APIs is very welcome, but please **no HTML parsing!** -[currencies_custom]: ../currencies/currencies_custom.tsv -[pr]: https://github.com/deanishe/alfred-convert/pulls -[yahoo-finance]: https://finance.yahoo.com/ \ No newline at end of file +[yahoo-finance]: https://finance.yahoo.com/ +[cryptocompare]: https://www.cryptocompare.com/ diff --git a/src/convert.py b/src/convert.py index e5737ae..5e237e9 100755 --- a/src/convert.py +++ b/src/convert.py @@ -10,7 +10,7 @@ """Drives Script Filter to show unit conversions in Alfred 3.""" -from __future__ import print_function, unicode_literals +from __future__ import print_function import os import sys @@ -44,6 +44,179 @@ # Q = ureg.Quantity +class NoToUnits(Exception): + """Raised if there are no to units (or defaults).""" + + +class Input(object): + """Parsed user query.""" + + def __init__(self, number, dimensionality, from_unit, to_unit=None): + self.number = number + self.dimensionality = dimensionality + self.from_unit = from_unit + self.to_unit = to_unit + + def __repr__(self): + return ('Input(number={!r}, dimensionality={!r}, ' + 'from_unit={!r}, to_unit={!r})').format( + self.number, + self.dimensionality, self.from_unit, self.to_unit) + + def __str__(self): + return self.__repr__() + + +class Formatter(object): + """Format a number.""" + + def __init__(self, decimal_places=2, decimal_separator='.', + thousands_separator=''): + self.decimal_places = decimal_places + self.decimal_separator = decimal_separator + self.thousands_separator = thousands_separator + + def formatted(self, n, unit=None): + sep = u'' + if self.thousands_separator: + sep = u',' + + fmt = u'{{:0{}.{:d}f}}'.format(sep, self.decimal_places) + num = fmt.format(n) + # log.debug('n=%r, fmt=%r, num=%r', n, fmt, num) + num = num.replace(',', '||comma||') + num = num.replace('.', '||point||') + num = num.replace('||comma||', self.thousands_separator) + num = num.replace('||point||', self.decimal_separator) + + if unit: + num = u'{} {}'.format(num, unit) + + return num + + +class Conversion(object): + """Results of a conversion. + + Attributes: + dimensionality (str): Dimensionality of conversion + from_number (float): Input + from_unit (str): Unit of input + to_number (float): Conversion result + to_unit (str): Unit of output + + """ + + def __init__(self, from_number, from_unit, to_number, to_unit, + dimensionality): + self.from_number = from_number + self.from_unit = from_unit + self.to_number = to_number + self.to_unit = to_unit + self.dimensionality = dimensionality + + def __str__(self): + return u'{:f} {} = {:f} {} {}'.format( + self.from_number, self.from_unit, self.to_number, self.to_unit, + self.dimensionality).encode('utf-8') + + def __repr__(self): + return ('Conversion(from_number={!r}, from_unit={!r}, ' + 'to_number={!r}, to_unit={!r}, dimensionality={!r}').format( + self.from_number, self.from_unit, self.to_number, + self.to_unit, self.dimensionality) + + +class Converter(object): + """Parse query and convert. + + Attributes: + defaults (defaults.Defaults): Default units for conversions. + + """ + + def __init__(self, defaults): + """Create new `Converter`. + + Args: + defaults (defaults.Defaults): Default units for conversions. + + """ + self.defaults = defaults + + def convert(self, i): + """Convert ``Input``.""" + if i.to_unit is not None: + units = [i.to_unit] + else: + units = [u for u in self.defaults.defaults(i.dimensionality) + if u != i.from_unit] + + if not units: + raise NoToUnits() + + results = [] + qty = ureg.Quantity(i.number, i.from_unit) + for u in units: + to_unit = ureg.Quantity(1, u) + conv = qty.to(to_unit) + log.debug('%s -> %s = %s', i.from_unit, u, conv) + results.append(Conversion(i.number, i.from_unit, + conv.magnitude, u, i.dimensionality)) + + return results + + def parse(self, query): + """Parse user query into `Input`.""" + # Parse number from start of query + qty = [] + for c in query: + if c in '1234567890.,': + qty.append(c) + else: + break + if not len(qty): + raise ValueError('Start your query with a number') + + tail = query[len(qty):].strip() + qty = float(''.join(qty)) + + if not len(tail): + raise ValueError('No units specified') + + log.debug('quantity : %s tail : %s', qty, tail) + + # Try to parse rest of query into a pair of units + from_unit = to_unit = None + units = [s.strip() for s in tail.split()] + from_unit = units[0] + if len(units) > 1: + to_unit = units[1] + if len(units) > 2: + raise ValueError('More than 2 units specified') + + try: + from_unit = ureg.Quantity(qty, from_unit) + except UndefinedUnitError: + raise ValueError('Unknown unit: ' + from_unit) + + if to_unit: + try: + to_unit = ureg.Quantity(1, to_unit) + except UndefinedUnitError: + raise ValueError('Unknown unit: ' + to_unit) + + tu = None + if to_unit: + tu = unicode(to_unit.units) + i = Input(from_unit.magnitude, unicode(from_unit.dimensionality), + unicode(from_unit.units), tu) + + log.debug(i) + + return i + + def format_number(n): """Format a floating point number with thousands/decimal separators. @@ -54,6 +227,7 @@ def format_number(n): sep = '' if THOUSANDS_SEPARATOR: sep = ',' + fmt = '{{:0{}.{:d}f}}'.format(sep, DECIMAL_PLACES) num = fmt.format(n) # log.debug('n=%r, fmt=%r, num=%r', n, fmt, num) @@ -107,80 +281,71 @@ def register_exchange_rates(exchange_rates): def convert(query): - """Parse query, calculate and return conversion result. - - Args: - query (unicode): Alfred's query. - - Raises: - ValueError: Raised if the query is incomplete or invalid. + """Perform conversion and send results to Alfred.""" + error = None + results = None - Returns: - tuple: (value, unit) + defs = Defaults(wf) + c = Converter(defs) - """ - # Parse number from start of query - qty = [] - for c in query: - if c in '1234567890.': - qty.append(c) - else: - break - if not len(qty): - raise ValueError('Start your query with a number') - - tail = query[len(qty):] - qty = float(''.join(qty)) - if not len(tail): - raise ValueError('No units specified') - - log.debug('quantity : %s tail : %s', qty, tail) - - # Try to parse rest of query into a pair of units - atoms = tail.split() - from_unit = to_unit = None - # Try splitting tail at every space until we arrive at a pair - # of units that `pint` understands - if len(atoms) == 1: - raise ValueError('No destination unit specified') - - q1 = q2 = '' - for i in range(len(atoms)): - from_unit = to_unit = None # reset so no old values spill over - q1 = ' '.join(atoms[:i + 1]).strip() - q2 = ' '.join(atoms[i + 1:]).strip() - log.debug('atoms : %r i : %d q1 : %s q2 : %s', atoms, i, q1, q2) - - if not len(q1) or not len(q2): # an empty unit - continue + try: + i = c.parse(query) + except ValueError as err: + log.critical(u'invalid query (%s): %s', query, err) + error = err.message + else: try: - from_unit = ureg.Quantity(qty, q1) - except UndefinedUnitError: - continue - else: - log.debug('from unit : %s', q1) - try: - to_unit = ureg.Quantity(1, q2) - except UndefinedUnitError: # Didn't make sense; try again - raise ValueError('Unknown unit : %s' % q2) - - log.debug("from '%s' to '%s'", from_unit.units, to_unit.units) - break # Got something! - - # Throw error if we arrive here with no units - if from_unit is None: - raise ValueError('Unknown unit : %s' % q1) - if to_unit is None: - raise ValueError('Unknown unit : %s' % q2) + results = c.convert(i) + log.debug('results=%r', results) + except NoToUnits: + log.critical(u'No to_units (or defaults) for %s', i.dimensionality) + error = u'No destination units (or defaults) for {}'.format( + i.dimensionality) + + except DimensionalityError as err: + log.critical(u'invalid conversion (%s): %s', query, err) + error = u"Can't convert from {} {} to {} {}".format( + err.units1, err.dim1, err.units2, err.dim2) + + if not error and not results: + error = 'Conversion input not understood' - conv = from_unit.to(to_unit) - number = format_number(conv.magnitude) - log.debug('%s %s' % (number, conv.units)) + if error: # Show error + wf.add_item(error, + 'For example: 2.5cm in | 178lb kg | 200m/s mph', + valid=False, icon=ICON_WARNING) - # log.debug('%r', str(conv.units)) + else: # Show results + f = Formatter(DECIMAL_PLACES, DECIMAL_SEPARATOR, THOUSANDS_SEPARATOR) + wf.setvar('query', query) + for conv in results: + value = copytext = f.formatted(conv.to_number, conv.to_unit) + if not COPY_UNIT: + copytext = f.formatted(conv.to_number) + + it = wf.add_item(value, + valid=True, + arg=copytext, + copytext=copytext, + largetext=value, + icon='icon.png') + + action = 'save' + name = 'Save' + if defs.is_default(conv.dimensionality, conv.to_unit): + action = 'delete' + name = 'Remove' + + mod = it.add_modifier('cmd', '{} {} as default unit for {}'.format( + name, conv.to_unit, conv.dimensionality)) + mod.setvar('action', action) + mod.setvar('unit', conv.to_unit) + mod.setvar('dimensionality', conv.dimensionality) - return number, str(conv.units), str(conv.dimensionality) + wf.send_feedback() + log.debug('finished') + return 0 def main(wf): @@ -231,64 +396,7 @@ def main(wf): wf.add_item(u'Updating exchange rates…', icon=ICON_INFO) - error = None - number = None - - try: - number, unit, dim = convert(query) - except UndefinedUnitError as err: - log.critical('unknown unit : %s', err.unit_names) - error = 'Unknown unit : {}'.format(err.unit_names) - - except DimensionalityError as err: - log.critical('invalid conversion : %s', err) - error = "Can't convert from {} {} to {} {}".format( - err.units1, err.dim1, err.units2, err.dim2) - - except ValueError as err: - log.critical('invalid query : %s', err) - error = err.message - - except Exception as err: - log.exception('%s : %s', err.__class__, err) - error = err.message - - if not error and not number: - error = 'Conversion input not understood' - - if error: # Show error - wf.add_item(error, - 'For example: 2.5cm in | 178lb kg | 200m/s mph', - valid=False, icon=ICON_WARNING) - - else: # Show result - defs = Defaults(wf) - value = copytext = '{} {}'.format(number, unit) - if not COPY_UNIT: - copytext = number - - it = wf.add_item(value, - valid=True, - arg=copytext, - copytext=copytext, - largetext=value, - icon='icon.png') - - action = 'save' - name = 'Save' - if defs.is_default(dim, unit): - action = 'delete' - name = 'Remove' - - mod = it.add_modifier('cmd', '{} {} as default unit for {}'.format( - name, unit, dim)) - mod.setvar('action', action) - mod.setvar('unit', unit) - mod.setvar('dimensionality', dim) - - wf.send_feedback() - log.debug('finished') - return 0 + return convert(query) if __name__ == '__main__': diff --git a/src/defaults.py b/src/defaults.py index 7ee56b2..7cd74c3 100644 --- a/src/defaults.py +++ b/src/defaults.py @@ -61,7 +61,7 @@ def defaults(self, dimensionality): """ return self._defs[dimensionality][:] - def save(self, dimensionality, unit): + def add(self, dimensionality, unit): """Save ``unit`` as default for ``dimensionality``. Args: @@ -119,7 +119,7 @@ def main(wf): unit = args[''] if args['save']: - defs.save(dimensionality, unit) + defs.add(dimensionality, unit) print(u'Saved {} as default unit for {}'.format(unit, dimensionality)) return diff --git a/src/info.plist b/src/info.plist index 6e53a16..5fa5a3a 100644 --- a/src/info.plist +++ b/src/info.plist @@ -7,6 +7,19 @@ connections 1E12C11D-30DB-44A8-AD75-F5BE7F2DA451 + + + destinationuid + 4489D9A5-121F-4F86-A8B9-6B6E7A49CEA6 + modifiers + 0 + modifiersubtext + + vitoclose + + + + 4489D9A5-121F-4F86-A8B9-6B6E7A49CEA6 destinationuid @@ -29,6 +42,19 @@ + 4F101B56-DE40-4D36-8D3D-E5E01A83C8D0 + + + destinationuid + 070B760D-0FE5-427B-9AFE-E617CDAF3601 + modifiers + 0 + modifiersubtext + + vitoclose + + + 54F0C711-EDE6-4387-B397-34AB8A8FFCB2 @@ -55,6 +81,19 @@ + C1740EC8-21DE-4062-A3F3-A46CDC61EFFF + + + destinationuid + 1E12C11D-30DB-44A8-AD75-F5BE7F2DA451 + modifiers + 0 + modifiersubtext + + vitoclose + + + CFE51A32-D227-42BA-966C-DBDED818F1D4 @@ -68,6 +107,19 @@ + DA12DA9F-7A81-4D31-BECF-ADF453BB814C + + + destinationuid + EF92F243-C49B-4DFC-B0A4-72317B2457A7 + modifiers + 0 + modifiersubtext + + vitoclose + + + EF92F243-C49B-4DFC-B0A4-72317B2457A7 @@ -93,6 +145,16 @@ vitoclose + + destinationuid + 4F101B56-DE40-4D36-8D3D-E5E01A83C8D0 + modifiers + 0 + modifiersubtext + + vitoclose + + createdby @@ -105,6 +167,42 @@ Convert objects + + config + + autopaste + + clipboardtext + {query} + transient + + + type + alfred.workflow.output.clipboard + uid + 607FA0B2-94A5-48E4-96E9-0BFA8872F7EE + version + 2 + + + config + + inputstring + {var:action} + matchcasesensitive + + matchmode + 0 + matchstring + + + type + alfred.workflow.utility.filter + uid + 54F0C711-EDE6-4387-B397-34AB8A8FFCB2 + version + 1 + config @@ -153,57 +251,31 @@ config - autopaste - - clipboardtext - {query} - transient - + triggerid + convert type - alfred.workflow.output.clipboard + alfred.workflow.trigger.external uid - 607FA0B2-94A5-48E4-96E9-0BFA8872F7EE - version - 2 - - - config - - inputstring - {var:action} - matchcasesensitive - - matchmode - 0 - matchstring - - - type - alfred.workflow.utility.filter - uid - 54F0C711-EDE6-4387-B397-34AB8A8FFCB2 + C1740EC8-21DE-4062-A3F3-A46CDC61EFFF version 1 config - lastpathcomponent + argument + query={query}, +variables={allvars} + cleardebuggertext - onlyshowifquerypopulated + processoutputs - removeextension - - text - {query} - title - Updated Default Units type - alfred.workflow.output.notification + alfred.workflow.utility.debug uid - 03379773-30CB-4371-BC49-8E2EA4C9947A + 4489D9A5-121F-4F86-A8B9-6B6E7A49CEA6 version 1 @@ -230,6 +302,27 @@ version 2 + + config + + lastpathcomponent + + onlyshowifquerypopulated + + removeextension + + text + {query} + title + Updated Default Units + + type + alfred.workflow.output.notification + uid + 03379773-30CB-4371-BC49-8E2EA4C9947A + version + 1 + config @@ -252,21 +345,13 @@ config - lastpathcomponent - - onlyshowifquerypopulated - - removeextension - - text - - title - {query} + triggerid + config type - alfred.workflow.output.notification + alfred.workflow.trigger.external uid - 14C63701-669A-43A3-BF6A-65A23759DA5F + DA12DA9F-7A81-4D31-BECF-ADF453BB814C version 1 @@ -315,6 +400,27 @@ version 2 + + config + + lastpathcomponent + + onlyshowifquerypopulated + + removeextension + + text + + title + {query} + + type + alfred.workflow.output.notification + uid + 14C63701-669A-43A3-BF6A-65A23759DA5F + version + 1 + config @@ -338,6 +444,40 @@ version 2 + + config + + externaltriggerid + convert + passinputasargument + + passvariables + + workflowbundleid + self + + type + alfred.workflow.output.callexternaltrigger + uid + 070B760D-0FE5-427B-9AFE-E617CDAF3601 + version + 1 + + + config + + argument + {var:query} + variables + + + type + alfred.workflow.utility.argument + uid + 4F101B56-DE40-4D36-8D3D-E5E01A83C8D0 + version + 1 + readme Offline Conversions @@ -367,69 +507,110 @@ UPDATE_INTERVAL is the number of minutes between exchange rate updates. 03379773-30CB-4371-BC49-8E2EA4C9947A xpos - 610 + 1070 + ypos + 170 + + 070B760D-0FE5-427B-9AFE-E617CDAF3601 + + xpos + 1070 ypos - 160 + 340 14C63701-669A-43A3-BF6A-65A23759DA5F xpos - 440 + 610 ypos - 300 + 340 1E12C11D-30DB-44A8-AD75-F5BE7F2DA451 + note + Perform conversion xpos - 40 + 210 ypos - 30 + 110 + + 4489D9A5-121F-4F86-A8B9-6B6E7A49CEA6 + + xpos + 440 + ypos + 140 + + 4F101B56-DE40-4D36-8D3D-E5E01A83C8D0 + + note + Set query from var:query + xpos + 980 + ypos + 370 54F0C711-EDE6-4387-B397-34AB8A8FFCB2 note Default action xpos - 250 + 650 ypos - 60 + 70 607FA0B2-94A5-48E4-96E9-0BFA8872F7EE xpos - 440 + 770 ypos - 30 + 40 96CC03AC-25D6-4FDB-AA8B-FCF145F4D597 xpos - 240 + 410 ypos - 300 + 340 + + C1740EC8-21DE-4062-A3F3-A46CDC61EFFF + + xpos + 40 + ypos + 110 CFE51A32-D227-42BA-966C-DBDED818F1D4 note Save/delete unit xpos - 250 + 650 ypos - 190 + 200 - EF92F243-C49B-4DFC-B0A4-72317B2457A7 + DA12DA9F-7A81-4D31-BECF-ADF453BB814C xpos 40 ypos - 300 + 340 + + EF92F243-C49B-4DFC-B0A4-72317B2457A7 + + note + View currencies and edit configuration + xpos + 210 + ypos + 340 F738EA53-3486-4210-B03B-CFB792FD1798 xpos - 440 + 770 ypos - 160 + 170 variables diff --git a/src/info.py b/src/info.py index 9c7e35d..cb290fa 100755 --- a/src/info.py +++ b/src/info.py @@ -42,7 +42,7 @@ ICON_WARNING, MATCH_ALL, MATCH_ALLCHARS, - Workflow, + Workflow3, ) from config import ( @@ -231,6 +231,6 @@ def main(wf): if __name__ == '__main__': - wf = Workflow() + wf = Workflow3() log = wf.logger sys.exit(wf.run(main)) diff --git a/src/test_convert.py b/src/test_convert.py new file mode 100755 index 0000000..c8fc199 --- /dev/null +++ b/src/test_convert.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# encoding: utf-8 +# +# Copyright (c) 2017 Dean Jackson +# +# MIT Licence. See http://opensource.org/licenses/MIT +# +# Created on 2017-07-16 +# + +"""Test converter.""" + +from __future__ import print_function, absolute_import + +from collections import namedtuple +import logging + +import pytest +from workflow import Workflow3 + +import convert +from defaults import Defaults + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger() +convert.log = logging.getLogger('convert') + + +T = namedtuple('T', 'number dimensionality from_unit to_unit') +C = namedtuple('C', 'from_number from_unit to_number to_unit dimensionality') + + +def verify_parsed(t1, t2): + """Verify results of `Converter.parse()`.""" + assert t1.number == t2.number + assert t1.dimensionality == t2.dimensionality + assert t1.from_unit == t2.from_unit + assert t1.to_unit == t2.to_unit + + +def verify_conversion(c1, c2): + """Verify results of `Converter.convert()`.""" + assert c1.from_number == c2.from_number + assert c1.from_unit == c2.from_unit + assert c1.to_number == c2.to_number + assert c1.to_unit == c2.to_unit + assert c1.dimensionality == c2.dimensionality + + +def test_invalid(): + """Test invalid input.""" + queries = [ + 'dave', # doesn't start with a number + '1.3', # no unit + '5 daves', # invalid units + '10 km m cm', # too many units + ] + c = convert.Converter(None) + for query in queries: + with pytest.raises(ValueError): + c.parse(query) + + +def test_valid(): + """Test valid input.""" + data = [ + ('1.3 km', T(1.3, '[length]', 'kilometer', None)), + ('1.3 km miles', T(1.3, '[length]', 'kilometer', 'mile')), + ('5 m/s kph', T(5.0, '[length] / [time]', 'meter/second', 'kph')), + ('21.3 m^2 acres', T(21.3, '[length] ** 2', u'meter²', 'acre')), + ] + c = convert.Converter(None) + for t in data: + i = c.parse(t[0]) + verify_parsed(t[1], i) + + +def test_conversion(): + """Test conversions.""" + data = [ + ('1km m', C(1, 'kilometer', 1000, 'meter', '[length]')), + ] + c = convert.Converter(None) + for t in data: + i = c.parse(t[0]) + res = c.convert(i) + verify_conversion(t[1], res[0]) + + +def test_defaults(): + """Test default conversions.""" + data = [ + ('1m', [ + C(1, 'meter', 100, 'centimeter', '[length]'), + C(1, 'meter', 0.001, 'kilometer', '[length]')]), + ('100g', [ + C(100, 'gram', 0.1, 'kilogram', '[mass]'), + C(100, 'gram', 100000, 'milligram', '[mass]')]), + ] + + wf = Workflow3() + if 'default_units' not in wf.settings: + wf.settings['default_units'] = {} + + wf.settings['default_units']['[length]'] = ['centimeter', 'kilometer'] + wf.settings['default_units']['[mass]'] = ['kilogram', 'milligram'] + + c = convert.Converter(Defaults(wf)) + + for t in data: + i = c.parse(t[0]) + res = c.convert(i) + assert len(res) == len(t[1]) + for j, r in enumerate(res): + log.debug(r) + verify_conversion(t[1][j], r) + + + +if __name__ == '__main__': # pragma: no cover + pytest.main([__file__])