From b0f106c64f3e3432ccdce46da25137e278ddb5f1 Mon Sep 17 00:00:00 2001 From: Neythen Date: Fri, 21 May 2021 14:24:37 +0100 Subject: [PATCH] scrolling news headlines added --- __pycache__/stockTicker.cpython-37.pyc | Bin 10006 -> 11232 bytes api_caller.py | 30 +++++- csv/crypto.csv | 4 +- csv/last_update.csv | 2 +- csv/news.csv | 21 ++++ csv/settings.csv | 2 +- csv/tickers.csv | 42 ++++---- display_gif | Bin 747 -> 821 bytes display_image | Bin 2202 -> 1364 bytes final.ppm | Bin 515727 -> 515727 bytes log.txt | 0 scroll_text.ppm | Bin 22862 -> 116847 bytes server.py | 21 +++- stockTicker.py | 134 +++++++++++++++++++------ templates/index.html | 3 +- test.py | 6 +- test.txt | 2 + 17 files changed, 195 insertions(+), 72 deletions(-) create mode 100644 csv/news.csv create mode 100755 log.txt create mode 100755 test.txt diff --git a/__pycache__/stockTicker.cpython-37.pyc b/__pycache__/stockTicker.cpython-37.pyc index 7f825192804ba296567f82a5057285290b898551..a90e8abe6a555e40e2d2eeaa679ea83cf86f7487 100644 GIT binary patch delta 3120 zcmaJ@TWnOv8J?MQ*|TRaUayUf!6vq`9hOo<2q{jAPzb~XObi&eHXEn|p2c0;te4r7 zdU4OPNgP#$mIN^gje1=xRZ~^1(!^@i+e_c7Uh+`2eb`c|4^<^pDOLIuwN=#bpLL zC2joM@}n{$y%%`ak%KZSeY9M;UFU>ql^Hm!lUwCS@ZTo4onV4)d?sMOcb5Ep%;4b&jvPF_7VR!ZU=!2=Ra>gXDI8s#HYrOnL z{r%|W#M}5GoR3k%6bS?(HQQWE(}KKiDF*(A=bv=1M zpVXqMzq?iDOU3y!7sqquU@TY6oeA=VnIF*98vxAGdz(6{-6w*D>ACUz^juC2-fh6N zMb7v|@VIykhYM&R&fst;Rs{HKRqTL=d>M2Kxa6S~+RNZ;AZlPP*lV?eqvzmTaRM7W zb-;Z$bPvwD(h0eALHNj38)NMFO0O&VcI<~1Z)ICCO z5j8;VDFT{OeT-l?fh5T3_fjp@*ndUr*D#k-0Oq8StvGK*rqamYQu{q(JWU&-9~Is0 z(0(4BfYlI0gou~RGmwEmNFl9dggLNkc4(1s1Ws7BDci?#UTmINWxNTaQnH1 zLQvX1RDR&W!D4=XDL!5L%=SWVv055LOFfDm|ATKE&-ltlQ|%vV_ML7{D|-|JcjU_kgEVBy=JX2%F4wg+E91O1N3++bjX1oOVS{!3u$skx1 zq#5~fVT;JMECvv6>6((TWn?$2*cS%_ABu=7l3o?Zz<1ytGYYjPj79_#L<3sN6Gziraw1)1op%YO;;>{&@a_tm> zWdl3T#@J+oEz!}X$o#_0U{DU~d{K|3HYZ3FGwT|35c>I4rg}#jjVc-*kTl*?6V-OS ztvib0|=5@(a%(AHDct*d{xraZif77|o z8HM4jUf=agZyc=*R|94@A9N-8w^tLJzQzx{LPPFS^=9TqwSS3RUZwGCC4alb)hxaG zvVQlzUjB96+dEro>$iKZ^O`=?yNkc4FZJ%jnW%r(+f{uR zhX~z>22nkNs9m@Tiw(woq=#@qGY{$0oEJXOS+#$qJ-js2ME3|-AJY&dJUXw=}&=7|dGHG*#v z4C^2D_Y4rzP_J!X)ZgfD@b`J^y_C1k%Xo3G8UG2-^M<{M{#SoLU(&q;n;R_3>XCt` rH~kP}v+)w$e5L|(^)aH+5TIs5?3)8gzE%Hqpf^@!5zlg4=mz_5tjV|u delta 1999 zcmaJ>Yiv|S6rP#;*t>V{-3O%)3YB*4W4CP-5fn(%q_q~YrPQ{t?Sd)LS+L#hcA33E zo7}aK5>lclFhY!IvNc8$jUlkX_=<^%F%eDtqkmR^@C$<);}0Lm592wvjr?;r_nULh zoHH}$c`I>gAlPl&CV}4*i&yp^?Y2q6O7er|3Rb&7 zfTUH?0#u=ydm)7}&TCk?7n#)34A4lAYC z?8~(28PJGFL=2X)GLb)4)XcP0c!GZ6Y(1Ps!0xA03u&g<5DrejRF(#fTNa z>d4mu5Go_#HS^WO&dfx5WO5>%5)bjod@gffZUoMlV5kE>tONr-uNuAp!XZWKRRd(b zpv+!(n9GXF5?O$-%>{v0U1d3h*;WXlmNv!6N&p#WsD*Ybdh@`Jkt`d<*y|wlaWF=6 z$0+)_iWHQS_BbghbIpzk*@Gg)Xo?G95x{7Bd9z$k7xET{OKrIHla)(@Q=wuQ^&o3u z$Xa-%6nz7N5_xlVz5Nt;1<^#0MNIy+I^KIfD-|g0L+D4?iGbxN1`u`u#5K_jOVT(z zd1(C5WF}Q+lhb87DZ=u6TSb+*64dQGdOrlUJk~m4@>*pb)GqunwLxl@ZdGcO4$9kA zoPAGZfAtUc94JDgBw!JHocem`47dublzu zbm^PMda5s1g8ZW?NneqJ%@+c%qFFt{Bk+P+>1zqotFor0i`^q~Z%f^L*`-{8`fTT_ zOU7CDCh!{Y9bEVLkAU|9-_H$?e+PJfS{GSI;ijXybb<1~TEeYrvH&A>T+1$kh7A@c zut%_xv&TRZ1jz>=@j1qnzi4_Ga18n71A+CSB?jXftc%c)*hAS)un2?2ZIFfJ#}BND zMNkKJV0Q9Vu=6MEczxmx>WYCf9rk9moQn<8Ie9a-adf3oFbU!kLKI;$!ixwE2spi# zC;I>A9tVn;M(C4c@y1R4K)w%SJdb%K%<#q?bO=!1rx>gjK9d=&ky?PwiXm^ryJ@Ao z8{f3O7f%{S@E+hD?3LlODD!F&Yizlf?|Xo$7MBrTN9dP@)`n;!kZ^02;WyWsmf2xc z8&ShDB1WZQ8-~$qX!7&cCYqB!wLZ99A!D+lZU369V3)M=I8nzPZ=?$BM(@<>aM|dX ap5aF`sZKu#^D$X!i~73^MGrHo(|-X3_P`qe diff --git a/api_caller.py b/api_caller.py index e335861..c941a0e 100644 --- a/api_caller.py +++ b/api_caller.py @@ -8,6 +8,8 @@ import datetime as dt import sys, os, base64, hashlib, hmac import requests from pycoingecko import CoinGeckoAPI +from newsapi import NewsApiClient + def readCSV(file_path, max_stocks): @@ -144,8 +146,25 @@ def updateCrypto(coins): CSV.write(coin+ ',' + str(response[coin]['usd']) + ',' + str(response[coin]['usd_24h_change']) + '\n') CSV.close() - + + +def updateNews(): + top_headlines = newsapi.get_top_headlines() + headline_titles = [top_headline['title'] for top_headline in top_headlines['articles']] + CSV = open('csv/news.csv', 'w+') + CSV.write('headline\n') + + for title in headline_titles: + CSV.write(title + '\n') + + CSV.close() + + + if __name__ == '__main__': + newsapi = NewsApiClient(api_key='cf08652bd17647b89aaf469a1a8198a9') + + finnhubAPIkey = "c24qddqad3ickpckgg80" #Finnhub finnhubsandboxAPIkey = "sandbox_c24qddqad3ickpckgg8g" #Finnhub sleeptime = 2 #minutes @@ -173,12 +192,13 @@ if __name__ == '__main__': NY_time = datetime.now(NY_zone) print(NY_time) - coins, coin_info = readCSV('csv/crypto.csv', max_stocks) - print(coins, coin_info) - updateCrypto(coins) - sys.exit() + while True: + coins, coin_info = readCSV('csv/crypto.csv', max_stocks) + updateCrypto(coins) + + #updateNews() NY_time = datetime.now(NY_zone) symbols, stock_info = readCSV('csv/tickers.csv', max_stocks) diff --git a/csv/crypto.csv b/csv/crypto.csv index d7fad47..1a752af 100644 --- a/csv/crypto.csv +++ b/csv/crypto.csv @@ -1,3 +1,3 @@ name,current,24hr change -bitcoin,40905,1.9630605505752174 -ethereum,2756.88,2.711695798229129 +bitcoin,41158,-3.112342608605254 +ethereum,2691.26,-8.560574933024819 diff --git a/csv/last_update.csv b/csv/last_update.csv index 7ff27cf..9a20847 100644 --- a/csv/last_update.csv +++ b/csv/last_update.csv @@ -1 +1 @@ -14/05/2021 06:29:45 +21/05/2021 09:21:44 diff --git a/csv/news.csv b/csv/news.csv new file mode 100644 index 0000000..8aa2bb9 --- /dev/null +++ b/csv/news.csv @@ -0,0 +1,21 @@ +headline, ' doesnt display, sort out comma +Total of 43 Changi Airport workers test positive for Covid-19; source likely worker who helped infected family from South Asia - The Straits Times +Covid-19 (May 21) - 6493 new cases, nationwide uptrend; 50 deaths - Malaysiakini +Lady Gaga says rape as teenager left her pregnant and caused psychotic break - The Guardian +Coronavirus: Spain to lift restrictions for UK and Japanese travellers - BBC News +Walsh wonderful as Warriors win thriller over Tigers - NRL.COM +Diana interview: Whistleblower wants apology from BBC bosses - BBC News +Latest Gombak death-in-custody due to heart attack, says S'gor CPO - Malaysiakini +Prince Harry tells Oprah that Diana's death led him to drink and drugs, accuses royals of 'total neglect' - NBC News +Manchester United passed on signing Man City star Ruben Dias - Manchester Evening News +Prince Harry: pain of Diana's death pushed me to drink and drugs - The Star Online +Kim Kardashian Accused Kourtney Kardashian Of Constantly "Degrading" Her Staff After A Brutal Confrontation With Her Nanny - BuzzFeed News +Overwatch 2 PvP is 5v5, Bastion reworked "from the ground up" - Eurogamer.net +Hospital staff 'should have checked for blood clots', say SA family - 9News +Cloudy skies to continue in Southern Luzon, Visayas and Mindanao due to ITCZ - INQUIRER.net +16-year-old Pune boy merges 50,000 images of Moon to create detailed picture - The Tribune +UK to offer Australia tariff-free trade deal despite farmers' fears - BBC News +Disha Patani does backflip to new BTS song Butter and Tiger Shroff is impressed, watch - Hindustan Times +Mop-up operations begin in Cape Town after flooding caused by heavy rain - News24 +New type of coronavirus originating in dogs found — study - The Edge Markets MY +House panel OKs bill for creation of PH virology institute, CDC - ABS-CBN News diff --git a/csv/settings.csv b/csv/settings.csv index bcf18cd..c970da5 100644 --- a/csv/settings.csv +++ b/csv/settings.csv @@ -1,2 +1,2 @@ speed,brightness -m,5 \ No newline at end of file +f,5 \ No newline at end of file diff --git a/csv/tickers.csv b/csv/tickers.csv index 089745b..f9cd618 100644 --- a/csv/tickers.csv +++ b/csv/tickers.csv @@ -1,22 +1,22 @@ name,current,opening -MSFT,243.03,241.8 -NFLX,486.66,489.13 -GOOG,2261.97,2261.09 -TSLA,571.69,601.545 -AAPL,124.97,124.58 -INTC,54.01,54.04 -TXN,178.99,179.99 -HPQ,32.39,32 -HOG,46.25,45.35 -LUV,59.93,58.97 -WMT,138.24,136.23 -BJ,45.99,45.63 -ETSY,156.59,163.3368 -G,44.51,43.84 -GDDY,79.29,80.92 -GNRC,293.36,294.17 -PEP,146.37,144.24 -STM,34.81,35.28 -YELP,38.14,37.39 -XRAY,66.61,65.83 -ZTS,170.85,168.37 +MSFT,246.48,243.96 +NFLX,501.67,489.55 +GOOG,2356.09,2328.04 +TSLA,586.78,575 +AAPL,127.31,125.23 +INTC,55.95,55.57 +TXN,185.3,182.28 +HPQ,32.04,31.98 +HOG,48.28,48.99 +LUV,59.92,60.92 +WMT,142.42,141.5 +BJ,46.16,48.26 +ETSY,172.36,166.28 +G,44.26,43.83 +GDDY,81.4,81.18 +GNRC,308.53,304.56 +PEP,147.23,145.25 +STM,36.18,35.79 +YELP,38.38,37.84 +XRAY,67.95,67.72 +ZTS,175.8,171.52 diff --git a/display_gif b/display_gif index c78d7a0507f9d38881ba68a8edba24ddeadae454..1eadae40c4dc16d28234c6cb4e150b88c535af93 100644 GIT binary patch literal 821 zcmZ?wbhEHb3}R4V_{abTcCTk}KVj&5t@x9L(+DV{_@CR)H6+;CF~HSG&w!Z`BIKEy zn4apJn4X!O&6}Q>o118Bpl4!gVrt5u12P3<9s|?=mVQp9SNx0TOp)~7d~f#FqpgoB zYG*uBz30A7sC#a<@$z?X4}4Di`sUN&*04Py8zYz$n+~0OchbbL(Rbq6<-r%1g`{qs zv{#|qUF1D?+^Wf*vv<@wIj8J5F!d`x{XFrO1>1_P)7iE>-Rdl6{vxDe>yjN6%tys` za@-7^`Ljac!psYj4GdOXTCXytvK)5(+F8~0N!Vb*Da+HE))Q7+duw~I&f?y)`}Zx& zIlrYJ{+8r<@cPys9jUijcTS)7QjD#h`$pz2&zrRy_R1#xyX(t0FXrDVUi+pvIX$`h z{&{uvdETe?t;>sYXuPv2^R;=7!oI36dv;oX^NZXc_AK-LEBetm3q47Mo9TO1`%LHAR>f_&~F6B!e`n449));p8W^Mgx~OwI?))=2^quDWyHc3Y%SjX?cLqOpVJ$-)!oaQYD_z9a`M}Hxk?-R zC)I{E#2WYXb~Ri26in`#v#2RBwXdXQ{)z=_*G(}gubeY+@$~lXb$x~TTUJe5xbr}L zZhv{rzIlh&9}n3XwYK=AyBf4B5oZHD!jM<>XOMub8hdRe81x1 zo7)%G4nv1w&3MWeoA7V>Kl`KJj8U9&S(@$pVaCT zwC#*>+@#VXtmd{N=H#Zs+&pT@$3iBcgf9_+*#r#K|MoKfw=*!T_|Ne5KPZsFU^I~N H1+p~&wK7U< diff --git a/display_image b/display_image index 1b52aea8269857fb686f6c0c960a6a7887f26cc2..7538cedaa3702c75d8f389f8fc187c0f753382c9 100644 GIT binary patch delta 1347 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 WP_|X5sW>U1S-;m8MUM@;(*Fe~g|dVI delta 15333 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 diff --git a/log.txt b/log.txt new file mode 100755 index 0000000..e69de29 diff --git a/scroll_text.ppm b/scroll_text.ppm index 9a254cf8c3aefc43a6e64428003626e5f9b350de..f4d2363202099894f1cac23dd14e30da29d7ed02 100755 GIT binary patch literal 116847 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 JB=D{T{tNF3ohtwU literal 22862 zcmeH@L2g(v2t>2aDSC!Psd9|o|1vEV3K}tZ%y$;?0_)2k505eC&+pf__s?JNZ?A73 zAFnU7W&$&TnZQh7CNLA23Csj$0yBY`z)WB!FcX*w%miivGl5$s@b~4#zU^|X+{@aI z?TSgau>YzMNoH6Srmi3Kj^oOWErQ&I+Mh7 zESb{WL|kPd0v0pFN-FVViMhyo>97*HJSk#p1$9MZgRz0b{_JE4Je*MFcPoIGF?^08a&327)PStn1D%%J{yM4R7!$fx47R*^{+v-&Sz7gZH$)~`Uw_6gEj@U*@ zr6ZCNGs8;27$htm1&Jw)g#%(9Gt5e-Di~2NQc-??;IFXV*Y;6Opl@jRCeL*IYOVNp zNM=|mtiRD!$E{?v*lAlZXDQv%Rat%@E7-8kI*AO%=!0=${Al}jrNWYDhLujCSJ{5H znwJXmj)P#%Qlg*RQv5(xuxFh$(gE9jZTTqqs`&p;CYZwbJLc$9#%$i~irtP2(Te-Q ztjB^mOYs$VDy!G6bbEzJmBZZfD^D-fX59m}_`7}s%6<(Sej7CMPa8Lu$Ds4PcuWrfT(?wAN>n{uGsx4r!= z(0Lkn__Rv!VZLP?U<`E~$6Xe%4`w6YVt8XzmBH4ktV&|XL@?Ww1LdANx$Ri?oJ8)~ z0oN0ZsVFSP$f8dY`54zl>dd@TWmi1H3>K?tB^)f(F%isJO1E@F*59?=xz#j~aA4Av z#FtoyK{w;^_;srPY|ctq*~F~YN!!KhyRA$*4uUyLt(v(<7w?KDONK>O!odQab+W^R zC&Cy9kOF2{NhN-4Vomsw+i^eQma|mZ$yK6wSM*sjebIeNKCZBU0ajMLCRYt~s<<&- zrL*B?SbrtYbYve5h^$EQEmtZ1&Y5Jzp5~(MyhO@jHe>~DF^e%W7&F5P@)0L29Ru?~ zXOS_ov)IrTQO+fJk;sY^I$Rj{J74sui_2Xja)!1a>(-BFFXaW&$&TnZQh7CNLA23Csj$0yBY`z)WB!a6W;59!b}? diff --git a/server.py b/server.py index bbb882e..30e2aaa 100644 --- a/server.py +++ b/server.py @@ -229,8 +229,8 @@ def AddLogo(): @app.route("/matrix", methods=['POST']) def matrix(): - global LastCommand - if "Run Display" in request.form: + global LastCommand + if "Run Stocks" in request.form: pass print('run display') #stock_ticker.runStockTicker(command, DelayTime, speedTime) @@ -240,13 +240,24 @@ def matrix(): #child.sendline('sent from server') #process = Popen(["sudo", "-E", "python3", "stockTicker.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE) + ticker.sendline('K') ticker.sendline('S') print('back in flask') LastCommand = 'Run display' - elif "Stop Display (at next refresh)" in request.form: + if "Run News" in request.form: + pass + print('run display') + ticker.sendline('K') + ticker.sendline('N') + + print('back in flask') + + + LastCommand = 'Run display' + elif "Stop Display (at next refresh)" in request.form: pass print('run display') #ticker.kill() @@ -256,14 +267,14 @@ def matrix(): ticker.sendline('K') except: print("none running") - elif "Shutdown the pi" in request.form: + elif "Shutdown the pi" in request.form: pass try: LastCommand = 'shutdown' os.system("sudo shutdown now") except: print("couldn't shutdown") - return hello() + return hello() if __name__ == "__main__": app.run(host='0.0.0.0', port=1024, debug=False) # the debuggger causes flickering diff --git a/stockTicker.py b/stockTicker.py index 2acd89a..190970b 100644 --- a/stockTicker.py +++ b/stockTicker.py @@ -97,7 +97,21 @@ class StockTicker(): offset_x -= 1 self.setImage(image, offset_x = offset_x, offset_y = offset_y) - time.sleep(delay) + + try: + msg = getInput() + if msg == 'K': + self.resetMatrix() + + return True + + self.process_msg(msg) + except KeyboardInterrupt: + sys.stdout.flush() + pass + + time.sleep(self.delay) + return False def scrollImageTransition(self, image_files, offset_x = 0, offset_y = 0, stocks = True): # use two image files and switch between them with a seemless transition @@ -138,9 +152,12 @@ class StockTicker(): time.sleep(self.delay) try: msg = getInput() + if msg == 'K': self.resetMatrix() kill = True + image1.close() + image2.close() break self.process_msg(msg) @@ -148,7 +165,9 @@ class StockTicker(): sys.stdout.flush() pass - + image1.close() + image2.close() + if kill: break if stocks: @@ -159,7 +178,9 @@ class StockTicker(): current_img = 1 offset_x = 0 - def displayText(self): + def displayTextRepeating(self): + + f = open('csv/scroll_text.csv', 'r') CSV = csv.reader(f) @@ -181,37 +202,80 @@ class StockTicker(): img.save('scroll_text.ppm') self.scrollImageTransition(['scroll_text.ppm', 'scroll_text.ppm'], offset_x = 128, offset_y = 0, stocks = False) + def displayText(self, text, font): - def displayGIF(self, gif_file): + - im = Image.open(gif_file) + + width, height = self.get_text_dimensions(text, font) + print(text) + print('dims:', width, height) + img = Image.new('RGB', (width + 50, 32)) + d = ImageDraw.Draw(img) - # To iterate through the entire gif - - i = 0 - while 1: - print(im.tell()) - try: - im.seek(i) - except EOFError: - print('finished') - i = 0 - im.seek(i) - # do something to im - self.setImage(im.convert('RGB')) - time.sleep(0.5) - i += 1 - try: - msg = getInput() - if msg == 'K': - self.resetMatrix() - break - - self.process_msg(msg) - except KeyboardInterrupt: - sys.stdout.flush() - pass + d.text((4, 0), text, fill=(255, 255, 255), font=font) + img.save('scroll_text.ppm') + return self.scrollImage('scroll_text.ppm', offset_x = 128, offset_y = 0) + + def displayNews(self): + font = ImageFont.load("./fonts/8x13.pil") + while True: + headlines = [] + f = open('csv/news.csv', 'r') + CSV = csv.reader(f) + next(CSV) + for row in CSV: + headlines.append(','.join(row)) + f.close() + + for headline in headlines: + killed = self.displayText(headline, font) + + if killed: + kill = True + if kill: break + if kill: break + + + + def displayGIF(self, gif_file): + with open('log.txt', "w") as log: + + try: + im = Image.open(gif_file) + + # To iterate through the entire gif + + i = 0 + while 1: + print(im.tell()) + try: + im.seek(i) + except EOFError: + print('finished') + i = 0 + im.seek(i) + # do something to im + self.setImage(im.convert('RGB')) + time.sleep(0.5) + i += 1 + try: + msg = getInput() + + if msg == 'K': + im.close() + self.resetMatrix() + break + + self.process_msg(msg) + except KeyboardInterrupt: + sys.stdout.flush() + pass + except Exception as e: + log.write(str(e)) + + #Using change between min and day price give appropriate arrow @@ -361,6 +425,8 @@ class StockTicker(): #os.system("sudo ./demo -D1 final.ppm -t " + str(displayTime) +" -m "+ str(speedDisplay) +" --led-gpio-mapping=adafruit-hat --led-rows=32 --led-cols=256") #os.system("sudo ./demo -D1 final.ppm -t " + str(self.displayTime) +" -m "+ str(self.speedDisplay) +" --led-gpio-mapping=adafruit-hat --led-rows=64 --led-cols=64 --led-slowdown-gpio=4 ") self.scrollImageTransition(['final.ppm', 'final.ppm'], offset_x = 0, offset_y = 0) + + #Retrieve symbols and stock info from the csv file def readCSV(self): @@ -441,6 +507,8 @@ class StockTicker(): self.getFullStockImage(1) self.displayStocks() + elif msg == 'N': #news + self.displayNews() # speed settings elif msg == 's': self.delay = 0.03 @@ -459,7 +527,7 @@ class StockTicker(): elif msg == 'T':# text - self.displayText() + self.displayTextRepeating() elif msg == 'I': # image @@ -471,6 +539,7 @@ class StockTicker(): self.displayGIF(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'display_gif')) + elif msg == 'K': # kill self.resetMatrix() @@ -478,7 +547,10 @@ if __name__ == '__main__': #print(sys.stdin.readlines()) stock_ticker = StockTicker() + #stock_ticker.process_msg('f') + #stock_ticker.displayNews() #stock_ticker.displayGIF('/home/pi/Desktop/stock_ticker/gifs/open.gif') + #stock_ticker.displayGIF('/home/pi/Desktop/stock_ticker/gifs/close.gif') diff --git a/templates/index.html b/templates/index.html index 0799a28..2a8bb68 100644 --- a/templates/index.html +++ b/templates/index.html @@ -10,7 +10,8 @@

- + +
diff --git a/test.py b/test.py index d277b27..201a80c 100644 --- a/test.py +++ b/test.py @@ -14,11 +14,7 @@ import pexpect from pycoingecko import CoinGeckoAPI if __name__ == '__main__': - - cg = CoinGeckoAPI() - - print(cg.get_price(ids='bitcoin, ethereum', vs_currencies = 'usd', include_24hr_change=True)) - + diff --git a/test.txt b/test.txt new file mode 100755 index 0000000..574dc93 --- /dev/null +++ b/test.txt @@ -0,0 +1,2 @@ +start +else: message: \ No newline at end of file