Fixed tons of bugs and made the return data cleaner
This commit is contained in:
parent
f57f5db449
commit
a0848a649b
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
test.lua
|
||||
537
DCL.dat
Normal file
537
DCL.dat
Normal file
@ -0,0 +1,537 @@
|
||||
currency code,currency name
|
||||
1ST,FirstBlood
|
||||
2GIVE,GiveCoin
|
||||
808,808Coin
|
||||
ABT,ArcBlock
|
||||
ABY,ArtByte
|
||||
AC,AsiaCoin
|
||||
ACT,Achain
|
||||
ADA,Cardano
|
||||
ADT,adToken
|
||||
ADX,AdEx
|
||||
AE,Aeternity
|
||||
AEON,Aeon
|
||||
AGI,SingularityNET
|
||||
AGRS,IDNI-Agoras
|
||||
AI,POLY-AI
|
||||
AID,AidCoin
|
||||
AION,Aion
|
||||
AIR,AirToken
|
||||
AKY,Akuya-Coin
|
||||
ALIS,ALIS
|
||||
AMBER,AmberCoin
|
||||
AMP,Synereo
|
||||
ANC,Anoncoin
|
||||
ANT,Aragon
|
||||
APPC,AppCoins
|
||||
APX,APX-Ventures
|
||||
ARDR,Ardor
|
||||
ARK,Ark
|
||||
ARN,Aeron
|
||||
AST,AirSwap
|
||||
ATB,ATBCoin
|
||||
ATM,ATMChain
|
||||
ATS,Authorship
|
||||
AUR,Auroracoin
|
||||
AVT,Aventus
|
||||
B3,B3Coin
|
||||
BAT,Basic-Attention-Token
|
||||
BAY,BitBay
|
||||
BBR,Boolberry
|
||||
BCAP,BCAP
|
||||
BCC,BitConnect
|
||||
BCD,Bitcoin-Diamond
|
||||
BCH,Bitcoin-Cash
|
||||
BCN,Bytecoin
|
||||
BCPT,BlockMason-Credit-Protocol-Token
|
||||
BCX,BitcoinX
|
||||
BCY,BitCrystals
|
||||
BDL,Bitdeal
|
||||
BEE,Bee-Token
|
||||
BELA,BelaCoin
|
||||
BET,DAO-Casino
|
||||
BFT,BF-Token
|
||||
BIS,Bismuth
|
||||
BITB,BitBean
|
||||
BITBTC,BitBTC
|
||||
BITCNY,BitCNY
|
||||
BITEUR,BitEUR
|
||||
BITGOLD,BitGOLD
|
||||
BITSILVER,BitSILVER
|
||||
BITUSD,BitUSD
|
||||
BIX,Bibox-Token
|
||||
BLITZ,Blitzcash
|
||||
BLK,Blackcoin
|
||||
BLN,Bolenum
|
||||
BLOCK,Blocknet
|
||||
BLZ,Bluzelle
|
||||
BMC,Blackmoon-Crypto
|
||||
BNB,Binance-Coin
|
||||
BNT,Bancor-Network-Token
|
||||
BNTY,Bounty0x
|
||||
BOST,BoostCoin
|
||||
BOT,Bodhi
|
||||
BQ,bitqy
|
||||
BRD,Bread
|
||||
BRK,Breakout-Coin
|
||||
BRX,Breakout-Stake
|
||||
BTA,Bata
|
||||
BTC,Bitcoin
|
||||
BTCD,BitcoinDark
|
||||
BTCP,Bitcoin-Private
|
||||
BTG,Bitcoin-Gold
|
||||
BTM,Bitmark
|
||||
BTS,BitShares
|
||||
BTSR,BTSR
|
||||
BTX,Bitcore
|
||||
BURST,Burstcoin
|
||||
BUZZ,BuzzCoin
|
||||
BYC,Bytecent
|
||||
BYTOM,Bytom
|
||||
C20,Crypto20
|
||||
CANN,CannabisCoin
|
||||
CAT,BlockCAT
|
||||
CCRB,CryptoCarbon
|
||||
CDT,Blox
|
||||
CFI,Cofound-it
|
||||
CHAT,ChatCoin
|
||||
CHIPS,Chips
|
||||
CLAM,Clams
|
||||
CLOAK,CloakCoin
|
||||
CMP,Compcoin
|
||||
CMT,CyberMiles
|
||||
CND,Cindicator
|
||||
CNX,Cryptonex
|
||||
COFI,CoinFi
|
||||
COSS,COSS
|
||||
COVAL,Circuits-Of-Value
|
||||
CRBIT,CreditBIT
|
||||
CREA,CreativeCoin
|
||||
CREDO,Credo
|
||||
CRW,Crown
|
||||
CSNO,BitDice
|
||||
CTR,Centra
|
||||
CTXC,Cortex
|
||||
CURE,CureCoin
|
||||
CVC,Civic
|
||||
DAI,Dai
|
||||
DAR,Darcrus
|
||||
DASH,Dash
|
||||
DATA,DATAcoin
|
||||
DAY,Chronologic
|
||||
DBC,DeepBrain-Chain
|
||||
DBIX,DubaiCoin
|
||||
DCN,Dentacoin
|
||||
DCR,Decred
|
||||
DCT,DECENT
|
||||
DDF,Digital-Developers-Fund
|
||||
DENT,Dent
|
||||
DFS,DFSCoin
|
||||
DGB,DigiByte
|
||||
DGC,Digitalcoin
|
||||
DGD,DigixDAO
|
||||
DICE,Etheroll
|
||||
DLT,Agrello-Delta
|
||||
DMD,Diamond
|
||||
DMT,DMarket
|
||||
DNT,district0x
|
||||
DOGE,DogeCoin
|
||||
DOPE,DopeCoin
|
||||
DRGN,Dragonchain
|
||||
DTA,Data
|
||||
DTB,Databits
|
||||
DYN,Dynamic
|
||||
EAC,EarthCoin
|
||||
EBST,eBoost
|
||||
EBTC,eBTC
|
||||
ECC,ECC
|
||||
ECN,E-coin
|
||||
EDG,Edgeless
|
||||
EDO,Eidoo
|
||||
EFL,Electronic-Gulden
|
||||
EGC,EverGreenCoin
|
||||
EKT,EDUCare
|
||||
ELA,Elastos
|
||||
ELEC,Electrify.Asia
|
||||
ELF,aelf
|
||||
ELIX,Elixir
|
||||
EMB,Embercoin
|
||||
EMC,Emercoin
|
||||
EMC2,Einsteinium
|
||||
ENG,Enigma
|
||||
ENJ,Enjin-Coin
|
||||
ENRG,EnergyCoin
|
||||
EOS,EOS
|
||||
EOT,EOT-Token
|
||||
EQT,EquiTrader
|
||||
ERC,EuropeCoin
|
||||
ETC,Ethereum-Classic
|
||||
ETH,Ethereum
|
||||
ETHD,Ethereum-Dark
|
||||
ETHOS,Ethos
|
||||
ETN,Electroneum
|
||||
ETP,Metaverse-Entropy
|
||||
ETT,EncryptoTel
|
||||
EVE,Devery
|
||||
EVX,Everex
|
||||
EXCL,ExclusiveCoin
|
||||
EXP,Expanse
|
||||
FCT,Factom
|
||||
FLDC,FoldingCoin
|
||||
FLO,FlorinCoin
|
||||
FLT,FlutterCoin
|
||||
FRST,FirstCoin
|
||||
FTC,Feathercoin
|
||||
FUEL,Etherparty
|
||||
FUN,FunFair
|
||||
GAM,Gambit
|
||||
GAME,GameCredits
|
||||
GAS,Gas
|
||||
GBG,Golos Gold
|
||||
GBX,GoByte
|
||||
GBYTE,Byteball
|
||||
GCR,GCRCoin
|
||||
GEO,GeoCoin
|
||||
GLD,GoldCoin
|
||||
GNO,Gnosis-Token
|
||||
GNT,Golem-Tokens
|
||||
GOLOS,Golos
|
||||
GRC,Gridcoin
|
||||
GRS,Groestlcoin
|
||||
GRWI,Growers-International
|
||||
GTC,Game
|
||||
GTO,Gifto
|
||||
GUP,Guppy
|
||||
GVT,Genesis-Vision
|
||||
GXS,GXShares
|
||||
HBN,HoboNickels
|
||||
HEAT,HEAT
|
||||
HMQ,Humaniq
|
||||
HPB,High-Performance-Blockchain
|
||||
HSR,Hshare
|
||||
HUSH,Hush
|
||||
HVN,Hive
|
||||
HXX,HexxCoin
|
||||
ICN,ICONOMI
|
||||
ICX,ICON
|
||||
IFC,Infinitecoin
|
||||
IFT,investFeed
|
||||
IGNIS,Ignis
|
||||
INCNT,Incent
|
||||
IND,Indorse-Token
|
||||
INF,InfChain
|
||||
INK,Ink
|
||||
INS,INS-Ecosystem
|
||||
INSTAR,Insights-Network
|
||||
INT,Internet-Node-Token
|
||||
INXT,Internxt
|
||||
IOC,IOCoin
|
||||
ION,ION
|
||||
IOP,Internet-of-People
|
||||
IOST,IOStoken
|
||||
IOTA,IOTA
|
||||
IOTX,IoTeX
|
||||
IQT,Iquant-Chain
|
||||
ITC,IoT-Chain
|
||||
IXC,iXcoin
|
||||
IXT,InsureX
|
||||
J8T,JET8
|
||||
JNT,Jibrel-Network
|
||||
KCS,KuCoin
|
||||
KICK,KickCoin
|
||||
KIN,KIN
|
||||
KMD,Komodo
|
||||
KNC,Kyber-Network
|
||||
KORE,KoreCoin
|
||||
LBC,LBRY-Credits
|
||||
LCC,Litecoin-Cash
|
||||
LEND,EthLend
|
||||
LEV,Leverj
|
||||
LGD,Legends-Room
|
||||
LINDA,Linda
|
||||
LINK,ChainLink
|
||||
LKK,Lykke
|
||||
LMC,LoMoCoin
|
||||
LOCI,LOCIcoin
|
||||
LOOM,Loom-Token
|
||||
LRC,Loopring
|
||||
LSK,Lisk
|
||||
LTC,Litecoin
|
||||
LUN,Lunyr
|
||||
MAID,MaidSafeCoin
|
||||
MANA,Decentraland
|
||||
MAX,Maxcoin
|
||||
MBRS,Embers
|
||||
MCAP,MCAP
|
||||
MCO,Monaco
|
||||
MDA,Moeda-Loyalty-Points
|
||||
MEC,Megacoin
|
||||
MED,MediBlock
|
||||
MEME,Memetic
|
||||
MER,Mercury
|
||||
MGC,MergeCoin
|
||||
MGO,MobileGo
|
||||
MINEX,Minex
|
||||
MINT,Mintcoin
|
||||
MITH,Mithril
|
||||
MKR,Maker
|
||||
MLN,Melon
|
||||
MNE,Minereum
|
||||
MNX,MinexCoin
|
||||
MOD,Modum
|
||||
MONA,MonaCoin
|
||||
MRT,Miners-Reward-Token
|
||||
MSP,Mothership
|
||||
MTH,Monetha
|
||||
MTN,MedToken
|
||||
MUE,MonetaryUnit
|
||||
MUSIC,Musicoin
|
||||
MYB,MyBit-Token
|
||||
MYST,Mysterium
|
||||
MZC,Mazacoin
|
||||
NAMO,Namocoin
|
||||
NANO,Nano
|
||||
NAS,Nebulas-Token
|
||||
NAV,Nav-Coin
|
||||
NBT,NuBits
|
||||
NCASH,Nucleus-Vision
|
||||
NDC,NeverDie-Coin
|
||||
NEBL,Neblio
|
||||
NEO,NEO
|
||||
NEOS,NeosCoin
|
||||
NET,Nimiq
|
||||
NLC2,NoLimitCoin
|
||||
NLG,Gulden
|
||||
NMC,Namecoin
|
||||
NMR,Numeraire
|
||||
NOBL,NobleCoin
|
||||
NOTE,DNotes
|
||||
NPXS,Pundi-X-Token
|
||||
NSR,NuShares
|
||||
NTO,Fujinto
|
||||
NULS,Nuls
|
||||
NVC,Novacoin
|
||||
NXC,Nexium
|
||||
NXS,Nexus
|
||||
NXT,Nxt
|
||||
OAX,openANX
|
||||
OBITS,Obits
|
||||
OCL,Oceanlab
|
||||
OCN,Odyssey
|
||||
ODEM,ODEM
|
||||
ODN,Obsidian
|
||||
OF,OFCOIN
|
||||
OK,OKCash
|
||||
OMG,OmiseGo
|
||||
OMNI,Omni
|
||||
ONION,DeepOnion
|
||||
ONT,Ontology
|
||||
OPT,Opus
|
||||
OST,Simple-Token
|
||||
PART,Particl
|
||||
PASC,PascalCoin
|
||||
PAY,TenX
|
||||
PBL,Pebbles
|
||||
PBT,Primalbase-Token
|
||||
PFR,Payfair
|
||||
PING,CryptoPing
|
||||
PINK,Pinkcoin
|
||||
PIVX,PIVX
|
||||
PIX,Lampix
|
||||
PLBT,Polybius
|
||||
PLR,Pillar
|
||||
PLU,Pluton
|
||||
POA,POA-Network
|
||||
POE,Poet
|
||||
POLY,Polymath
|
||||
POSW,PoSW-Coin
|
||||
POT,PotCoin
|
||||
POWR,Power-Ledger
|
||||
PPC,Peercoin
|
||||
PPT,Populous
|
||||
PPY,Peerplays
|
||||
PRG,Paragon-Coin
|
||||
PRL,Oyster-Pearl
|
||||
PRO,Propy
|
||||
PST,Primas
|
||||
PTC,Pesetacoin
|
||||
PTOY,Patientory
|
||||
PURA,Pura
|
||||
QASH,QASH
|
||||
QAU,Quantum
|
||||
QLC,Qlink
|
||||
QRK,Quark
|
||||
QRL,Quantum-Resistant-Ledger
|
||||
QSP,Quantstamp
|
||||
QTL,Quatloo
|
||||
QTUM,Qtum
|
||||
QWARK,Qwark
|
||||
R,Revain
|
||||
RADS,Radium
|
||||
RAIN,Condensate
|
||||
RBIES,Rubies
|
||||
RBX,Ripto-Bux
|
||||
RBY,RubyCoin
|
||||
RCN,Ripio-Credit-Network
|
||||
RDD,ReddCoin
|
||||
RDN,Raiden-Network-Token
|
||||
REC,Regalcoin
|
||||
RED,Redcoin
|
||||
REP,Augur
|
||||
REQ,Request-Network
|
||||
RHOC,RChain
|
||||
RIC,Riecoin
|
||||
RISE,Rise
|
||||
RLC,RLC-Token
|
||||
RLT,RouletteToken
|
||||
RPX,Red-Pulse
|
||||
RRT,Recovery-Right-Tokens
|
||||
RUFF,Ruff
|
||||
RUP,Rupee
|
||||
RVT,Rivetz
|
||||
SAFEX,SafeExchangeCoin
|
||||
SALT,Salt
|
||||
SAN,Santiment-Network-Token
|
||||
SBD,Steem-Dollars
|
||||
SBTC,Super-Bitcoin
|
||||
SC,Siacoin
|
||||
SEELE,Seele
|
||||
SEQ,Sequence
|
||||
SHIFT,SHIFT
|
||||
SIB,SIBCoin
|
||||
SIGMA,SIGMAcoin
|
||||
SIGT,Signatum
|
||||
SJCX,Storjcoin-X
|
||||
SKIN,SkinCoin
|
||||
SKY,Skycoin
|
||||
SLR,SolarCoin
|
||||
SLS,SaluS
|
||||
SMART,SmartCash
|
||||
SMT,SmartMesh
|
||||
SNC,SunContract
|
||||
SNGLS,SingularDTV
|
||||
SNM,SONM
|
||||
SNRG,Synergy
|
||||
SNT,Status-Network-Token
|
||||
SOC,All-Sports
|
||||
SOUL,Phantasma
|
||||
SPANK,SpankChain
|
||||
SPC,SpaceChain
|
||||
SPHR,Sphere
|
||||
SPR,SpreadCoin
|
||||
SRN,Sirin-Labs-Token
|
||||
START,Startcoin
|
||||
STEEM,Steem
|
||||
STK,STK-Token
|
||||
STORJ,Storj
|
||||
STORM,Storm
|
||||
STQ,Storiqa
|
||||
STRAT,Stratis
|
||||
STX,Stox
|
||||
SUB,Substratum
|
||||
SWFTC,SwftCoin
|
||||
SWIFT,Bitswift
|
||||
SWT,Swarm-City
|
||||
SYNX,Syndicate
|
||||
SYS,SysCoin
|
||||
TAAS,Taas
|
||||
TAU,Lamden
|
||||
TCC,The-ChampCoin
|
||||
TFL,True-Flip
|
||||
THC,HempCoin
|
||||
THETA,Theta-Token
|
||||
TIME,Time
|
||||
TIX,Blocktix
|
||||
TKN,TokenCard
|
||||
TKR,Trackr
|
||||
TKS,Tokes
|
||||
TNB,Time-New-Bank
|
||||
TNT,Tierion
|
||||
TOA,ToaCoin
|
||||
TRAC,OriginTrail
|
||||
TRC,Terracoin
|
||||
TRCT,Tracto
|
||||
TRIG,Triggers
|
||||
TRST,Trustcoin
|
||||
TRUE,TrueChain
|
||||
TRUST,TrustPlus
|
||||
TRX,Tronix
|
||||
TUSD,TrueUSD
|
||||
TX,TransferCoin
|
||||
UBQ,Ubiq
|
||||
UKG,UnikoinGold
|
||||
ULA,Ulatech
|
||||
UNB,UnbreakableCoin
|
||||
UNITY,SuperNET
|
||||
UNO,Unobtanium
|
||||
UNY,Unity-Ingot
|
||||
UP,UpToken
|
||||
URO,Uro
|
||||
USDT,Tether
|
||||
UTK,UTrust
|
||||
VEE,BLOCKv
|
||||
VEN,VeChain
|
||||
VERI,Veritaseum
|
||||
VIA,Viacoin
|
||||
VIB,Viberate
|
||||
VIBE,Vibe
|
||||
VIVO,VIVO
|
||||
VOISE,Voise
|
||||
VOX,Voxels
|
||||
VPN,VPNCoin
|
||||
VRC,Vericoin
|
||||
VRM,Verium
|
||||
VRS,Veros
|
||||
VSL,vSlice
|
||||
VTC,Vertcoin
|
||||
VTR,vTorrent
|
||||
WABI,WaBi
|
||||
WAN,Wanchain
|
||||
WAVES,Waves
|
||||
WAX,Wax-Token
|
||||
WCT,Waves-Community
|
||||
WDC,WorldCoin
|
||||
WGO,WavesGo
|
||||
WGR,Wagerr
|
||||
WINGS,Wings
|
||||
WPR,WePower
|
||||
WTC,Walton
|
||||
WTT,Giga-Watt-Token
|
||||
XAS,Asch
|
||||
XAUR,Xaurum
|
||||
XBC,Bitcoin-Plus
|
||||
XBY,XtraBYtes
|
||||
XCN,Cryptonite
|
||||
XCP,Counterparty
|
||||
XDN,DigitalNote
|
||||
XEL,Elastic
|
||||
XEM,NEM
|
||||
XID,Sphere-Identity
|
||||
XLM,Stellar
|
||||
XMG,Magi
|
||||
XMR,Monero
|
||||
XMT,Metal
|
||||
XMY,Myriadcoin
|
||||
XPM,Primecoin
|
||||
XRL,Rialto
|
||||
XRP,Ripple
|
||||
XSPEC,Spectrecoin
|
||||
XST,Stealthcoin
|
||||
XTZ,Tezos
|
||||
XUC,Exchange-Union
|
||||
XVC,Vcash
|
||||
XVG,Verge
|
||||
XWC,WhiteCoin
|
||||
XZC,ZCoin
|
||||
XZR,ZrCoin
|
||||
YEE,Yee
|
||||
YOYOW,YOYOW
|
||||
ZCC,ZcCoin
|
||||
ZCL,Zclassic
|
||||
ZCO,Zebi
|
||||
ZEC,Zcash
|
||||
ZEN,ZenCash
|
||||
ZET,Zetacoin
|
||||
ZIL,Zilliqa
|
||||
ZLA,Zilla
|
||||
ZRX,0x
|
||||
157
PCL.dat
Normal file
157
PCL.dat
Normal file
@ -0,0 +1,157 @@
|
||||
currency code,currency name
|
||||
AED,United Arab Emirates Dirham
|
||||
AFN,Afghan Afghani
|
||||
ALL,Albanian Lek
|
||||
AMD,Armenian Dram
|
||||
ANG,Netherlands Antillean Guilder
|
||||
AOA,Angolan Kwanza
|
||||
ARS,Argentine Peso
|
||||
AUD,Australian Dollar
|
||||
AWG,Aruban Florin
|
||||
AZN,Azerbaijani Manat
|
||||
BAM,Bosnia-Herzegovina Convertible Mark
|
||||
BBD,Barbadian Dollar
|
||||
BDT,Bangladeshi Taka
|
||||
BGN,Bulgarian Lev
|
||||
BHD,Bahraini Dinar
|
||||
BIF,Burundian Franc
|
||||
BMD,Bermudan Dollar
|
||||
BND,Brunei Dollar
|
||||
BOB,Bolivian Boliviano
|
||||
BRL,Brazilian Real
|
||||
BSD,Bahamian Dollar
|
||||
BTN,Bhutanese Ngultrum
|
||||
BWP,Botswanan Pula
|
||||
BZD,Belize Dollar
|
||||
CAD,Canadian Dollar
|
||||
CDF,Congolese Franc
|
||||
CHF,Swiss Franc
|
||||
CLF,Chilean Unit of Account UF
|
||||
CLP,Chilean Peso
|
||||
CNH,Chinese Yuan Offshore
|
||||
CNY,Chinese Yuan
|
||||
COP,Colombian Peso
|
||||
CUP,Cuban Peso
|
||||
CVE,Cape Verdean Escudo
|
||||
CZK,Czech Republic Koruna
|
||||
DJF,Djiboutian Franc
|
||||
DKK,Danish Krone
|
||||
DOP,Dominican Peso
|
||||
DZD,Algerian Dinar
|
||||
EGP,Egyptian Pound
|
||||
ERN,Eritrean Nakfa
|
||||
ETB,Ethiopian Birr
|
||||
EUR,Euro
|
||||
FJD,Fijian Dollar
|
||||
FKP,Falkland Islands Pound
|
||||
GBP,British Pound Sterling
|
||||
GEL,Georgian Lari
|
||||
GHS,Ghanaian Cedi
|
||||
GIP,Gibraltar Pound
|
||||
GMD,Gambian Dalasi
|
||||
GNF,Guinean Franc
|
||||
GTQ,Guatemalan Quetzal
|
||||
GYD,Guyanaese Dollar
|
||||
HKD,Hong Kong Dollar
|
||||
HNL,Honduran Lempira
|
||||
HRK,Croatian Kuna
|
||||
HTG,Haitian Gourde
|
||||
HUF,Hungarian Forint
|
||||
IDR,Indonesian Rupiah
|
||||
ILS,Israeli New Sheqel
|
||||
INR,Indian Rupee
|
||||
IQD,Iraqi Dinar
|
||||
IRR,Iranian Rial
|
||||
JEP,Jersey Pound
|
||||
JMD,Jamaican Dollar
|
||||
JOD,Jordanian Dinar
|
||||
JPY,Japanese Yen
|
||||
KES,Kenyan Shilling
|
||||
KGS,Kyrgystani Som
|
||||
KHR,Cambodian Riel
|
||||
KMF,Comorian Franc
|
||||
KPW,North Korean Won
|
||||
KRW,South Korean Won
|
||||
KWD,Kuwaiti Dinar
|
||||
KYD,Cayman Islands Dollar
|
||||
KZT,Kazakhstani Tenge
|
||||
LAK,Laotian Kip
|
||||
LBP,Lebanese Pound
|
||||
LKR,Sri Lankan Rupee
|
||||
LRD,Liberian Dollar
|
||||
LSL,Lesotho Loti
|
||||
LYD,Libyan Dinar
|
||||
MAD,Moroccan Dirham
|
||||
MDL,Moldovan Leu
|
||||
MGA,Malagasy Ariary
|
||||
MKD,Macedonian Denar
|
||||
MMK,Myanma Kyat
|
||||
MNT,Mongolian Tugrik
|
||||
MOP,Macanese Pataca
|
||||
MRO,Mauritanian Ouguiya (pre-2018)
|
||||
MRU,Mauritanian Ouguiya
|
||||
MUR,Mauritian Rupee
|
||||
MVR,Maldivian Rufiyaa
|
||||
MWK,Malawian Kwacha
|
||||
MXN,Mexican Peso
|
||||
MYR,Malaysian Ringgit
|
||||
MZN,Mozambican Metical
|
||||
NAD,Namibian Dollar
|
||||
NGN,Nigerian Naira
|
||||
NOK,Norwegian Krone
|
||||
NPR,Nepalese Rupee
|
||||
NZD,New Zealand Dollar
|
||||
OMR,Omani Rial
|
||||
PAB,Panamanian Balboa
|
||||
PEN,Peruvian Nuevo Sol
|
||||
PGK,Papua New Guinean Kina
|
||||
PHP,Philippine Peso
|
||||
PKR,Pakistani Rupee
|
||||
PLN,Polish Zloty
|
||||
PYG,Paraguayan Guarani
|
||||
QAR,Qatari Rial
|
||||
RON,Romanian Leu
|
||||
RSD,Serbian Dinar
|
||||
RUB,Russian Ruble
|
||||
RUR,Old Russian Ruble
|
||||
RWF,Rwandan Franc
|
||||
SAR,Saudi Riyal
|
||||
SBDf,Solomon Islands Dollar
|
||||
SCR,Seychellois Rupee
|
||||
SDG,Sudanese Pound
|
||||
SEK,Swedish Krona
|
||||
SGD,Singapore Dollar
|
||||
SHP,Saint Helena Pound
|
||||
SLL,Sierra Leonean Leone
|
||||
SOS,Somali Shilling
|
||||
SRD,Surinamese Dollar
|
||||
SYP,Syrian Pound
|
||||
SZL,Swazi Lilangeni
|
||||
THB,Thai Baht
|
||||
TJS,Tajikistani Somoni
|
||||
TMT,Turkmenistani Manat
|
||||
TND,Tunisian Dinar
|
||||
TOP,Tongan Pa'anga
|
||||
TRY,Turkish Lira
|
||||
TTD,Trinidad and Tobago Dollar
|
||||
TWD,New Taiwan Dollar
|
||||
TZS,Tanzanian Shilling
|
||||
UAH,Ukrainian Hryvnia
|
||||
UGX,Ugandan Shilling
|
||||
USD,United States Dollar
|
||||
UYU,Uruguayan Peso
|
||||
UZS,Uzbekistan Som
|
||||
VND,Vietnamese Dong
|
||||
VUV,Vanuatu Vatu
|
||||
WST,Samoan Tala
|
||||
XAF,CFA Franc BEAC
|
||||
XAG,Silver Ounce
|
||||
XAU,Gold Ounce
|
||||
XCD,East Caribbean Dollar
|
||||
XDR,Special Drawing Rights
|
||||
XOF,CFA Franc BCEAO
|
||||
XPF,CFP Franc
|
||||
YER,Yemeni Rial
|
||||
ZAR,South African Rand
|
||||
ZMW,Zambian Kwacha
|
||||
ZWL,Zimbabwean Dollar
|
||||
@ -1,8 +1,20 @@
|
||||
local https = require("ssl.https")
|
||||
local bin = require("bin")
|
||||
local alpha = {}
|
||||
alpha.APIKey = ""
|
||||
function string:split( inSplitPattern, outResults)
|
||||
local _,https = pcall(require,"ssl.https")
|
||||
local _,luajitrequest = pcall(require,"luajit-request")
|
||||
local request
|
||||
if https then
|
||||
function request(url)
|
||||
return https.request(url)
|
||||
end
|
||||
end
|
||||
if luajitrequest and not https then
|
||||
function request(url)
|
||||
return luajitrequest.send(url).body
|
||||
end
|
||||
end
|
||||
function string:split(inSplitPattern, outResults)
|
||||
if not outResults then
|
||||
outResults = {}
|
||||
end
|
||||
@ -24,7 +36,7 @@ function alpha.getPhysicalCurrencyList(force)
|
||||
if bin.fileExists("PCL.dat") and not force then
|
||||
dat = bin.load("PCL.dat").data
|
||||
else
|
||||
dat = https.request("https://www.alphavantage.co/physical_currency_list/")
|
||||
dat = request("https://www.alphavantage.co/physical_currency_list/")
|
||||
bin.new(dat):tofile("PCL.dat")
|
||||
end
|
||||
if alpha.pcl then return alpha.pcl end
|
||||
@ -43,7 +55,7 @@ function alpha.getDigitalCurrencyList(force)
|
||||
if bin.fileExists("DCL.dat") and not force then
|
||||
dat = bin.load("DCL.dat").data
|
||||
else
|
||||
dat = https.request("https://www.alphavantage.co/digital_currency_list/")
|
||||
dat = request("https://www.alphavantage.co/digital_currency_list/")
|
||||
bin.new(dat):tofile("DCL.dat")
|
||||
end
|
||||
if alpha.dcl then return alpha.dcl end
|
||||
@ -58,20 +70,21 @@ function alpha.getDigitalCurrencyList(force)
|
||||
return c
|
||||
end
|
||||
function alpha.dataToTable(data)
|
||||
local c = {}
|
||||
local order = {}
|
||||
local c = {
|
||||
MetaData = {},
|
||||
History = {}
|
||||
}
|
||||
local lines = data:lines(str)
|
||||
local tab = {}
|
||||
local tag = lines[1]:split(",")
|
||||
for i = 2,#lines-1 do
|
||||
tab = lines[i]:split(",")
|
||||
c[tab[1]]={}
|
||||
local t={}
|
||||
c.History[#c.History+1]=t
|
||||
for e = 1,#tag do
|
||||
order[#order+1]=tab[1]
|
||||
c[tab[1]][tag[e]]=tab[e]
|
||||
t[tag[e]]=tab[e]
|
||||
end
|
||||
end
|
||||
c.order = order
|
||||
return c
|
||||
end
|
||||
local function simpleparse(command,symbols,outputsize,interval)
|
||||
@ -89,11 +102,15 @@ local function simpleparse(command,symbols,outputsize,interval)
|
||||
end
|
||||
for i=1,#symbols do
|
||||
cmd = "https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&datatype=csv&apikey="..alpha.APIKey..outputsize..str
|
||||
dat = https.request(cmd)
|
||||
dat = request(cmd)
|
||||
if dat:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
else
|
||||
data[symbols[i]]=alpha.dataToTable(dat)
|
||||
data[i]=alpha.dataToTable(dat)
|
||||
data[i].MetaData = {
|
||||
Symbol = symbols[i],
|
||||
MostRecentData = data[i].History[1]
|
||||
}
|
||||
end
|
||||
end
|
||||
return data
|
||||
@ -122,6 +139,30 @@ end
|
||||
function alpha.timeSeriesMonthlyAdjusted(symbols,outputsize)
|
||||
return simpleparse("TIME_SERIES_MONTHLY_ADJUSTED",symbols,outputsize)
|
||||
end
|
||||
-- api.GLOBAL_QUOTE
|
||||
function alpha.globalQuote(symbols)
|
||||
local cmd
|
||||
local data = {}
|
||||
if type(symbols)=="string" then
|
||||
symbols = {symbols}
|
||||
end
|
||||
local str = ""
|
||||
for i=1,#symbols do
|
||||
cmd = "https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol="..symbols[i].."&datatype=csv&apikey="..alpha.APIKey
|
||||
dat = request(cmd)
|
||||
print(dat)
|
||||
if dat:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
else
|
||||
data[i]=alpha.dataToTable(dat)
|
||||
data[i].MetaData = {
|
||||
Symbol = symbols[i],
|
||||
MostRecentData = data[i].History[1]
|
||||
}
|
||||
end
|
||||
end
|
||||
return data
|
||||
end
|
||||
-- api.TIME_SERIES_INTRADAY
|
||||
local _interval = {
|
||||
["1min"]=true,
|
||||
@ -143,7 +184,7 @@ end
|
||||
|
||||
-- api.CURRENCY_EXCHANGE_RATE
|
||||
function alpha.currencyExchangeRate(from,to)
|
||||
local dat = https.request("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency="..from.."&to_currency="..to.."&apikey="..alpha.APIKey)
|
||||
local dat = request("https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency="..from.."&to_currency="..to.."&apikey="..alpha.APIKey)
|
||||
if dat:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
else
|
||||
@ -162,14 +203,14 @@ local function simpleFXParse(cmd,from,to,interval,outputsize)
|
||||
outputsize = "&outputsize="..outputsize
|
||||
end
|
||||
interval = interval or ""
|
||||
print("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
|
||||
local dat = https.request("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
|
||||
local dat = request("https://www.alphavantage.co/query?function="..cmd.."&from_symbol="..from.."&to_symbol="..to..interval.."&apikey="..alpha.APIKey.."&datatype=csv"..outputsize)
|
||||
if dat:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
else
|
||||
local data = alpha.dataToTable(dat)
|
||||
data.From = from
|
||||
data.To = to
|
||||
data.MetaData.From = from
|
||||
data.MetaData.To = to
|
||||
data.MetaData.MostRecentData = data.History[1]
|
||||
return data
|
||||
end
|
||||
end
|
||||
@ -187,11 +228,11 @@ function alpha.currencyExchangeDaily(from,to,outputsize)
|
||||
end
|
||||
-- api.FX_WEEKLY
|
||||
function alpha.currencyExchangeWeekly(from,to,outputsize)
|
||||
return simpleFXParse("FX_WEEKLY",from,to)
|
||||
return simpleFXParse("FX_WEEKLY",from,to,nil,outputsize)
|
||||
end
|
||||
-- api.FX_MONTHLY
|
||||
function alpha.currencyExchangeMonthly(from,to,outputsize)
|
||||
return simpleFXParse("FX_MONTHLY",from,to)
|
||||
return simpleFXParse("FX_MONTHLY",from,to,nil,outputsize)
|
||||
end
|
||||
local function simpleDigitalParse(command,symbols,market)
|
||||
local data = {}
|
||||
@ -199,11 +240,14 @@ local function simpleDigitalParse(command,symbols,market)
|
||||
symbols = {symbols}
|
||||
end
|
||||
for i=1,#symbols do
|
||||
dat = https.request("https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&market="..market.."&datatype=csv&apikey="..alpha.APIKey)
|
||||
dat = request("https://www.alphavantage.co/query?function="..command.."&symbol="..symbols[i].."&market="..market.."&datatype=csv&apikey="..alpha.APIKey)
|
||||
if dat:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
else
|
||||
data[symbols[i]]=alpha.dataToTable(dat)
|
||||
data[symbols[i]].MetaData.Symbol = symbols[i]
|
||||
data[symbols[i]].MetaData.Market = market
|
||||
data[symbols[i]].MetaData.MostRecentData = data[symbols[i]].History[1]
|
||||
end
|
||||
end
|
||||
return data
|
||||
@ -238,11 +282,14 @@ local function technicalParsers(cmd,symbol,interval,time_period,series_type,t)
|
||||
for i,v in pairs(t or {}) do
|
||||
extras=extras.."&"..i.."="..v
|
||||
end
|
||||
local data = https.request("https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&interval="..interval.."&time_period="..time_period.."&series_type="..series_type.."&apikey="..alpha.APIKey..extras)
|
||||
local data = request("https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&interval="..interval.."&time_period="..time_period.."&series_type="..series_type.."&apikey="..alpha.APIKey..extras)
|
||||
if data:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
end
|
||||
return alpha.dataToTable(data)
|
||||
data = alpha.dataToTable(data)
|
||||
data.MetaData.Symbol = symbol
|
||||
data.MetaData.MostRecentData = data.History[1]
|
||||
return data
|
||||
end
|
||||
local function technicalParsers2(cmd,symbol,t)
|
||||
local extras = ""
|
||||
@ -250,11 +297,15 @@ local function technicalParsers2(cmd,symbol,t)
|
||||
extras=extras.."&"..i.."="..v
|
||||
end
|
||||
local c = "https://www.alphavantage.co/query?function="..cmd.."&datatype=csv&symbol="..symbol.."&apikey="..alpha.APIKey..extras
|
||||
local data = https.request(c)
|
||||
print(c)
|
||||
local data = request(c)
|
||||
if data:find("Invalid API call") then
|
||||
return nil, "Invalid API call"
|
||||
end
|
||||
return alpha.dataToTable(data)
|
||||
data = alpha.dataToTable(data)
|
||||
data.MetaData.Symbol = symbol
|
||||
data.MetaData.MostRecentData = data.History[1]
|
||||
return data
|
||||
end
|
||||
-- api.SMA
|
||||
function alpha.getSMA(symbol,interval,time_period,series_type)
|
||||
@ -311,7 +362,10 @@ function alpha.getSTOCH(symbol,t)
|
||||
return technicalParsers2("STOCH",symbol,t)
|
||||
end
|
||||
-- api.STOCHF
|
||||
function alpha.getSTOCHF(symbol,t)
|
||||
function alpha.getSTOCHF(symbol,interval,t)
|
||||
local t = t or {
|
||||
interval = interval or "monthly"
|
||||
}
|
||||
return technicalParsers2("STOCHF",symbol,t)
|
||||
end
|
||||
-- api.RSI
|
||||
@ -635,7 +689,7 @@ function alpha.getHTPhasor(symbol,interval,time_period,series_type,t)
|
||||
end
|
||||
-- api.SECTOR
|
||||
function alpha.getSectorPreformance()
|
||||
local raw = https.request("https://www.alphavantage.co/query?function=SECTOR&apikey="..alpha.APIKey)
|
||||
local raw = request("https://www.alphavantage.co/query?function=SECTOR&apikey="..alpha.APIKey)
|
||||
raw=raw:gsub(" ","")
|
||||
local c = {}
|
||||
for section,data in raw:gmatch([["(.-)": {.(.-).}]]) do
|
||||
|
||||
397
luajit-request/init.lua
Normal file
397
luajit-request/init.lua
Normal file
@ -0,0 +1,397 @@
|
||||
--[[
|
||||
LuaJIT-Request
|
||||
Lucien Greathouse
|
||||
Wrapper for LuaJIT-cURL for easy HTTP(S) requests.
|
||||
|
||||
Copyright (c) 2016 Lucien Greathouse
|
||||
|
||||
This software is provided 'as-is', without any express
|
||||
or implied warranty. In no event will the authors be held
|
||||
liable for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, andto alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
]]
|
||||
|
||||
local path = (...):gsub("%.init$", ""):match("%.?(.-)$") .. "."
|
||||
|
||||
local ffi = require("ffi")
|
||||
local curl = require(path .. "luajit-curl")
|
||||
local request
|
||||
|
||||
local function url_encode(str)
|
||||
if (str) then
|
||||
str = str:gsub("\n", "\r\n")
|
||||
str = str:gsub("([^%w %-%_%.%~])", function(c)
|
||||
return string.format ("%%%02X", string.byte(c))
|
||||
end)
|
||||
str = str:gsub(" ", "%%20")
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
local function cookie_encode(str, name)
|
||||
str = str:gsub("[,;%s]", "")
|
||||
|
||||
if (name) then
|
||||
str = str:gsub("=", "")
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local auth_map = {
|
||||
BASIC = ffi.cast("long", curl.CURLAUTH_BASIC),
|
||||
DIGEST = ffi.cast("long", curl.CURLAUTH_DIGEST),
|
||||
NEGOTIATE = ffi.cast("long", curl.CURLAUTH_NEGOTIATE)
|
||||
}
|
||||
|
||||
local errors = {
|
||||
unknown = 0,
|
||||
timeout = 1,
|
||||
connect = 2,
|
||||
resolve_host = 3
|
||||
}
|
||||
|
||||
local code_map = {
|
||||
[curl.CURLE_OPERATION_TIMEDOUT] = {
|
||||
errors.timeout, "Connection timed out"
|
||||
},
|
||||
[curl.CURLE_COULDNT_RESOLVE_HOST] = {
|
||||
errors.resolve_host, "Couldn't resolve host"
|
||||
},
|
||||
[curl.CURLE_COULDNT_CONNECT] = {
|
||||
errors.connect, "Couldn't connect to host"
|
||||
}
|
||||
}
|
||||
|
||||
request = {
|
||||
error = errors,
|
||||
|
||||
version = "2.4.0",
|
||||
version_major = 2,
|
||||
version_minor = 4,
|
||||
version_patch = 0,
|
||||
|
||||
--[[
|
||||
Send an HTTP(S) request to the URL at 'url' using the HTTP method 'method'.
|
||||
Use the 'args' parameter to optionally configure the request:
|
||||
- method: HTTP method to use. Defaults to "GET", but can be any HTTP verb like "POST" or "PUT"
|
||||
- headers: Dictionary of additional HTTP headers to send with request
|
||||
- data: Dictionary or string to send as request body
|
||||
- cookies: Dictionary table of cookies to send
|
||||
- timeout: How long to wait for the connection to be made before giving up
|
||||
- allow_redirects: Whether or not to allow redirection. Defaults to true
|
||||
- body_stream_callback: A method to call with each piece of the response body.
|
||||
- header_stream_callback: A method to call with each piece of the resulting header.
|
||||
- transfer_info_callback: A method to call with transfer progress data.
|
||||
- auth_type: Authentication method to use. Defaults to "none", but can also be "basic", "digest" or "negotiate"
|
||||
- username: A username to use with authentication. 'auth_type' must also be specified.
|
||||
- password: A password to use with authentication. 'auth_type' must also be specified.
|
||||
- files: A dictionary of file names to their paths on disk to upload via stream.
|
||||
|
||||
If both body_stream_callback and header_stream_callback are defined, a boolean true will be returned instead of the following object.
|
||||
|
||||
The return object is a dictionary with the following members:
|
||||
- code: The HTTP status code the response gave. Will not exist if header_stream_callback is defined above.
|
||||
- body: The body of the response. Will not exist if body_stream_callback is defined above.
|
||||
- headers: A dictionary of headers and their values. Will not exist if header_stream_callback is defined above.
|
||||
- headers_raw: A raw string containing the actual headers the server sent back. Will not exist if header_stream_callback is defined above.
|
||||
- set_cookies: A dictionary of cookies given by the "Set-Cookie" header from the server. Will not exist if the server did not set any cookies.
|
||||
|
||||
If an error occured, false will be returned along with a curl error code and a message.
|
||||
]]
|
||||
send = function(url, args)
|
||||
local handle = curl.curl_easy_init()
|
||||
local header_chunk
|
||||
local out_buffer
|
||||
local headers_buffer
|
||||
args = args or {}
|
||||
|
||||
local callbacks = {}
|
||||
local gc_handles = {}
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_URL, url)
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_SSL_VERIFYPEER, 1)
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_SSL_VERIFYHOST, 2)
|
||||
|
||||
if (args.data and type(args.data) ~= "table") then
|
||||
local default_content_type = "application/octet-stream"
|
||||
if (not args.headers) then
|
||||
args.headers = {
|
||||
["content-type"] = default_content_type
|
||||
}
|
||||
else
|
||||
local has_content_type = false
|
||||
for header_name, _ in pairs(args.headers) do
|
||||
if header_name:lower() == "content-type" then
|
||||
has_content_type = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not has_content_type then
|
||||
args.headers["content-type"] = default_content_type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (args.method) then
|
||||
local method = string.upper(tostring(args.method))
|
||||
|
||||
if (method == "GET") then
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPGET, 1)
|
||||
elseif (method == "POST") then
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_POST, 1)
|
||||
args.data = args.data or "" -- https://github.com/curl/curl/issues/1625#issuecomment-312456910
|
||||
else
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_CUSTOMREQUEST, method)
|
||||
end
|
||||
end
|
||||
|
||||
if (args.headers) then
|
||||
for key, value in pairs(args.headers) do
|
||||
header_chunk = curl.curl_slist_append(header_chunk, tostring(key) .. ":" .. tostring(value))
|
||||
end
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPHEADER, header_chunk)
|
||||
end
|
||||
|
||||
if (args.auth_type) then
|
||||
local auth = string.upper(tostring(args.auth_type))
|
||||
|
||||
if (auth_map[auth]) then
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPAUTH, auth_map[auth])
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_USERNAME, tostring(args.username))
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_PASSWORD, tostring(args.password or ""))
|
||||
elseif (auth ~= "NONE") then
|
||||
error("Unsupported authentication type '" .. auth .. "'")
|
||||
end
|
||||
end
|
||||
|
||||
if (args.body_stream_callback) then
|
||||
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
|
||||
args.body_stream_callback(ffi.string(data, size * nmeb))
|
||||
return size * nmeb
|
||||
end)
|
||||
|
||||
table.insert(callbacks, callback)
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_WRITEFUNCTION, callback)
|
||||
else
|
||||
out_buffer = {}
|
||||
|
||||
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
|
||||
table.insert(out_buffer, ffi.string(data, size * nmeb))
|
||||
return size * nmeb
|
||||
end)
|
||||
|
||||
table.insert(callbacks, callback)
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_WRITEFUNCTION, callback)
|
||||
end
|
||||
|
||||
if (args.header_stream_callback) then
|
||||
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
|
||||
args.header_stream_callback(ffi.string(data, size * nmeb))
|
||||
return size * nmeb
|
||||
end)
|
||||
|
||||
table.insert(callbacks, callback)
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HEADERFUNCTION, callback)
|
||||
else
|
||||
headers_buffer = {}
|
||||
|
||||
local callback = ffi.cast("curl_callback", function(data, size, nmeb, user)
|
||||
table.insert(headers_buffer, ffi.string(data, size * nmeb))
|
||||
return size * nmeb
|
||||
end)
|
||||
|
||||
table.insert(callbacks, callback)
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HEADERFUNCTION, callback)
|
||||
end
|
||||
|
||||
if (args.transfer_info_callback) then
|
||||
local callback = ffi.cast("curl_xferinfo_callback", function(client, dltotal, dlnow, ultotal, ulnow)
|
||||
args.transfer_info_callback(tonumber(dltotal), tonumber(dlnow), tonumber(ultotal), tonumber(ulnow))
|
||||
return 0
|
||||
end)
|
||||
|
||||
table.insert(callbacks, callback)
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_NOPROGRESS, 0)
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_XFERINFOFUNCTION, callback)
|
||||
end
|
||||
|
||||
if (args.follow_redirects == nil) then
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_FOLLOWLOCATION, true)
|
||||
else
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_FOLLOWLOCATION, not not args.follow_redirects)
|
||||
end
|
||||
|
||||
if (args.data) then
|
||||
if (type(args.data) == "table") then
|
||||
local buffer = {}
|
||||
for key, value in pairs(args.data) do
|
||||
table.insert(buffer, ("%s=%s"):format(url_encode(key), url_encode(value)))
|
||||
end
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_POSTFIELDS, table.concat(buffer, "&"))
|
||||
else
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_POSTFIELDS, tostring(args.data))
|
||||
end
|
||||
end
|
||||
|
||||
local post
|
||||
if (args.files) then
|
||||
post = ffi.new("struct curl_httppost*[1]")
|
||||
local lastptr = ffi.new("struct curl_httppost*[1]")
|
||||
|
||||
for key, value in pairs(args.files) do
|
||||
local file = ffi.new("char[?]", #value, value)
|
||||
|
||||
table.insert(gc_handles, file)
|
||||
|
||||
local res = curl.curl_formadd(
|
||||
post, lastptr,
|
||||
ffi.new("int", curl.CURLFORM_COPYNAME), key,
|
||||
ffi.new("int", curl.CURLFORM_FILE), file,
|
||||
ffi.new("int", curl.CURLFORM_END)
|
||||
)
|
||||
end
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_HTTPPOST, post[0])
|
||||
end
|
||||
|
||||
-- Enable the cookie engine
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_COOKIEFILE, "")
|
||||
|
||||
if (args.cookies) then
|
||||
local cookie_out
|
||||
|
||||
if (type(args.cookies) == "table") then
|
||||
local buffer = {}
|
||||
for key, value in pairs(args.cookies) do
|
||||
table.insert(buffer, ("%s=%s"):format(cookie_encode(key, true), cookie_encode(value)))
|
||||
end
|
||||
|
||||
cookie_out = table.concat(buffer, "; ")
|
||||
else
|
||||
cookie_out = tostring(args.cookies)
|
||||
end
|
||||
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_COOKIE, cookie_out)
|
||||
end
|
||||
|
||||
if (tonumber(args.timeout)) then
|
||||
curl.curl_easy_setopt(handle, curl.CURLOPT_CONNECTTIMEOUT, tonumber(args.timeout))
|
||||
end
|
||||
|
||||
local code = curl.curl_easy_perform(handle)
|
||||
|
||||
if (code ~= curl.CURLE_OK) then
|
||||
local num = tonumber(code)
|
||||
|
||||
if (code_map[num]) then
|
||||
return false, code_map[num][1], code_map[num][2]
|
||||
end
|
||||
|
||||
return false, request.error.unknown, "Unknown error", num
|
||||
end
|
||||
|
||||
local out
|
||||
|
||||
if (out_buffer or headers_buffer) then
|
||||
local headers, status, parsed_headers, raw_cookies, set_cookies
|
||||
|
||||
if (headers_buffer) then
|
||||
-- In case we got multiple responses (e.g. 100 - Continue or 302 Redirects)
|
||||
-- we want to only return the last response
|
||||
local start_index = 1
|
||||
for i, resp_line in ipairs(headers_buffer) do
|
||||
if resp_line:match("^HTTP/(.-)%s+(%d+)%s+(.+)\r\n$") then
|
||||
start_index = i
|
||||
end
|
||||
end
|
||||
local last_request_headers = {}
|
||||
for i = start_index, #headers_buffer do
|
||||
table.insert(last_request_headers, headers_buffer[i])
|
||||
end
|
||||
headers = table.concat(last_request_headers)
|
||||
status = tonumber(headers:match("%s+(%d+)%s+"))
|
||||
|
||||
parsed_headers = {}
|
||||
|
||||
for key, value in headers:gmatch("\n([^:]+): *([^\r\n]*)") do
|
||||
parsed_headers[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
local cookielist = ffi.new("struct curl_slist*[1]")
|
||||
curl.curl_easy_getinfo(handle, curl.CURLINFO_COOKIELIST, cookielist)
|
||||
if cookielist[0] ~= nil then
|
||||
raw_cookies, set_cookies = {}, {}
|
||||
local cookielist = ffi.gc(cookielist[0], curl.curl_slist_free_all)
|
||||
local cookie = cookielist
|
||||
|
||||
repeat
|
||||
local raw = ffi.string(cookie[0].data)
|
||||
table.insert(raw_cookies, raw)
|
||||
|
||||
local domain, subdomains, path, secure, expiration, name, value = raw:match("^(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.*)$")
|
||||
set_cookies[name] = value
|
||||
cookie = cookie[0].next
|
||||
until cookie == nil
|
||||
end
|
||||
|
||||
out = {
|
||||
body = table.concat(out_buffer),
|
||||
headers = parsed_headers,
|
||||
raw_cookies = raw_cookies,
|
||||
set_cookies = set_cookies,
|
||||
code = status,
|
||||
raw_headers = headers
|
||||
}
|
||||
else
|
||||
out = true
|
||||
end
|
||||
|
||||
curl.curl_easy_cleanup(handle)
|
||||
curl.curl_slist_free_all(header_chunk)
|
||||
|
||||
if (post) then
|
||||
curl.curl_formfree(post[0])
|
||||
end
|
||||
gc_handles = {}
|
||||
|
||||
for i, v in ipairs(callbacks) do
|
||||
v:free()
|
||||
end
|
||||
|
||||
return out
|
||||
end,
|
||||
|
||||
init = function()
|
||||
curl.curl_global_init(curl.CURL_GLOBAL_ALL)
|
||||
end,
|
||||
|
||||
close = function()
|
||||
curl.curl_global_cleanup()
|
||||
end
|
||||
}
|
||||
|
||||
request.init()
|
||||
|
||||
return request
|
||||
1016
luajit-request/luajit-curl.lua
Normal file
1016
luajit-request/luajit-curl.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,8 @@ returns a list of Physical Currencies
|
||||
#alpha.getDigitalCurrencyList(boolean: force)
|
||||
returns a list of Digital Currencies
|
||||
**Note:** The above 2 function have a table format of key: "currency code" val: "name of currency". Also these functions also cache a file containing a list of currencies. Setting force to true will force the function to request a list of currencies again.
|
||||
#alpha.globalQuote(symbols)
|
||||
returns the current price and metadata of a stock or a table of stocks
|
||||
#alpha.timeSeriesDaily(symbols, outputsize)
|
||||
#alpha.timeSeriesDailyAdjusted(symbols,outputsize)
|
||||
#alpha.timeSeriesWeekly(symbols,outputsize)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user