From 36900ef8e0e84fd53476127997fb95fbe236861e Mon Sep 17 00:00:00 2001 From: anshuman444 Date: Fri, 5 Dec 2025 19:25:57 +0530 Subject: [PATCH] Refactor: cleanup comments and add docstrings --- src/__pycache__/async_request.cpython-312.pyc | Bin 0 -> 2460 bytes src/__pycache__/main.cpython-312.pyc | Bin 0 -> 2271 bytes src/__pycache__/scene_split.cpython-312.pyc | Bin 3170 -> 3862 bytes src/__pycache__/slideshow.cpython-312.pyc | Bin 3095 -> 3527 bytes src/__pycache__/text_to_img.cpython-312.pyc | Bin 1387 -> 1652 bytes src/async_request.py | 27 +++++++++++--- src/main.py | 29 +++++++++++---- src/scene_split.py | 34 +++++++++++++++++- src/slideshow.py | 31 ++++++++++++++-- src/text_to_img.py | 19 +++++++--- 10 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 src/__pycache__/async_request.cpython-312.pyc create mode 100644 src/__pycache__/main.cpython-312.pyc diff --git a/src/__pycache__/async_request.cpython-312.pyc b/src/__pycache__/async_request.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4aefa6e3e75f3456fca5c3287c1023c27c3110fb GIT binary patch literal 2460 zcma)8Uu+ab7@yhQyWQUH^-9}7Yfv_VZI3@C8W3p=a&2RbnxYg!I7PDEowi%&n0;6dIlsfmr@!Eg3Y?=C^(T<4o_ zzM1d0Gv9o_Fa0@@h#_d>4_+|jC_)d|By8RaOjdsaaTV!E$61u|N1VYh=dxUm&+s`R zBVeTS1W$!NAqI@PK%#nt@FYrvaju(LqBl=^1UUzN^#>4dAPj*iqNxDh+YyK&E^^=F z1GhO;XFW z3byjrq0u7>C8rC-b`-}_oJpeCd7>HP2GNzHhu>7D4QJ9bPZ(#2sjyJ>$2`O|ov;Ty zjo}9oRr*xJnsl6e|4`N-rZegXIyImi0q9_DeKUNqU=wBBqTVNhgY>V1!s{q~wnGDV zb{=rC;VO;$!B%%+2UPmlQ@;a_I~92D6M_5dqlZSk3osDF)UpMgz}N&eX6Z9NSPHws zlx>+K=h`54PGgi!8F{_K4zQE5|3 z9i>R6wP#uC{fkF!J7KY!+_6@H4yr$UY##)ui(TnW_zQd>dYuR5>tveaZ^l8ph0{p* zF$!84VJ5j~x>GDmI31VEEh5v~M6kOO+>+2UYSxWtR>5?%fN6k@Pz!XABrMl_k~r%W znF=W3?F__1FnTn>jj4V?aM=C5R^%4~lwow@6@)HC92Q%zO-Z3vADwup7lk4!;)Q^4 zAqqwf{&KjtJ{H#rIR~}RJC#SU2$1S>S^yjSHITIFxN zId!<1sChySOE0G=aJj9;XiEC0Y}T<)~T3Eab)rRjl!Km#`%Gt|KYY z6@xnCCYp+n8=L13AcK*Mt58YQYjPCBZ6$|Ii}v9pBaQ_(t?X&a;n-M|D(O&6cE z8P6G~6@|7k(}wV|LL%GrDX=pi`!ooT$$xeNlUI`4s>y9D$)4q8&wTIw4I4izT-kgn z{ZQ^$k+)RkE#J!X#}>6)d+sU+m*w=s_U@~@KHpW6?zX2^o|QN`XvwAH)(ND;LAOD5J~0UDARYv!Crm| z4{}0ze-!j3gu%YVVWtbw!Hwcl3=bycrMSrSb`k976jt5sf!({+ywOk2s=0iY^lMgb zH&n8`1+VP#r^t*Ofof48k66qevHufNNxBgR+5y6iIx~60oS=-Nl+_a2$;>=dZ2uj2 z!103kq=#^MS}<>*Rd7N63rH{LEWMB=2k3KPV`ans4n&Q|82^e|;qN!JxhBMLUrAh1 z_Ewd>H3XAeL*8)PxieIG`^cTw%I|ygO6I*)wp{B<;_ao58iHYdc(G$qTkN_q;!SUB z-cUJw)E}7#?5aJB#MCT*PfA>xu85mvg?n*%R=Ov}W+T6&_^kMG{DXK^e)^hL+B4s^ Qxc9ES{}(hsx4}{W0WwEoLI3~& literal 0 HcmV?d00001 diff --git a/src/__pycache__/main.cpython-312.pyc b/src/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..361f39ca122f5fc2c6f467e9c46148fa9953370a GIT binary patch literal 2271 zcmaJ>UuYCZ7@xWQb9;X_x%|~67g=qzUYkU1EtFVngC;0qY-?$8QI2zGF7EYi_qsdR zOAeI_2u3P+MW_c72=v9G55DxZ6htWW1L~tIND1<1=L1g{7z8Ww?0x6l2 zm}OHIvtlY@R!vpRVKWR&8VM1J$TyVhQuFvb$c)fPu4g?vLTmgng89$&RSg)CKBCe% z2@{-^iFQsgbzs(8c+3?mx#WKtX^cc#EM_~P5+r&ZH*w-r2W@Yy%}%i&qn%gLLZ}rL zs04|>wC*B$Yi)LmQ!nrL(00<+x_3W1F@(@@$i?h6H;{JPeHD?!f;ndkbdm0sLS7MwNx9vxaIlX?NY9PlR`sA3>uLih|G!%X0FfXY=l~5>pcg^Y#s#V6 zAMo+6OPa}9{2JPYd|VD;bPQqmx%gs6I)=*Ff=E+)8T|+IK@*eef6T>CRU$rfz1dMV z!vgG8loHF1yqm&-Mjgu~wlf{XvTmMGFI~*AQ-SJHR`MKcwI@XWyifVx$~W-1f|v;M z$E&`HoU*pP_Hr7vvh#Xa>l;Hk`1;n5e~=ilH4QoO#lDRFH*yxILX~f$28?}qn(=&t zouYlv0uGmQE?+T0^9^_|z*XjE{Gd(-}yc;n3f za>>~4GcPq}d;+&{*9_*08=H_(V?WJiN_hq{Tw{x{f6J)gnM$ca$n^uc>2*^|p!%mu z%+7=N1?Ev2Xobw@l-Qo1!X9_i=SCRMW4>n{FJx?Iv^X1dT0GITAWt{%_1Xc}#__}O zsG`3TNQ<5?&y~-gojY6md^x=3k=Axezo5grw&jtmo^a zs6`#H#V_V<#=t+nWLebrv!#4~c5|h3s#G{hJ;Ti!z5tFH0ghGz0gi#$nuzX(0B%b7MPLpNB%&*05n^Jm$L2u#q_lzGf^2);{JrSHg$E2_s`v zBCA|(wh|XP?-1N06?wGiOjn}K9?$u%6X5b=8O}nBtF}X^!z%Gl>;i}aDrd~7XogQM z*CF6;ponv+!9ZmIv00##X6e#=?eTrk7Ra2~*X;Ck`lEEWL`Zew{R^`ik|JTK+403gd;pnyV-PW*LI2}7DPp!Y3^tc zp@0(h1=t2{oF-6f_6^emG9TG(RyiKTo$}OitUP?&J+fZEoA9UwV zkGD&py;pEaDNpx$yI{$U_bf8b@Ztk$AgReo*Kxqg&M|V0Z-NboAG^EpGlbF*J9eI$kY3Xz#66YWc-fLm$3YTGDq{ zCm+b&)kF8>?j^aq_G$g}wef3jHwJgym3KagppLCi+t8l<_{Yhg#+S#Ymh~e`V^iOi zuYGZIs1~n(RNq%;jkcjhvefoQV{Gad{YW+1v|zX{Ei1`I{F|&-_n$vFcW^#e-@G_} zSKh{b7=&cQ1J&$3wSP(NzoRCr5-6UJ*N)bEzCKnvRG(?6+m})55lTFp#^75+8F{ht wF-C14;%8v-U_(hh_XnXk-*-%4>6Xzkp{uv{_D*z3x3Mx24d3okCX(U50dPk+c>n+a literal 0 HcmV?d00001 diff --git a/src/__pycache__/scene_split.cpython-312.pyc b/src/__pycache__/scene_split.cpython-312.pyc index afc6267d5fa6844b1a955a5efeb9396490271e75..abdbc7686641b0dd4689ec871c81464b239cec02 100644 GIT binary patch delta 1400 zcmZux&u<$=6rPR8zt(HJxJiiP#u-FK?6kE?P*v3`L{({3D!9;Af|Ouwy<=x#z3a}- z5}X5$P!EYfYO0kW6_-?8g19t7LOt;hfKXC{fQ^EzRzl+DDmiiD&DtTB$VfBu<~`5% zz5U)BKNy}xNeVhxdY8QP=p!zU5o3nh8T%V(WSa*2W3(z)jHhJ&j+kQ%Ycf|+XgsZbfa^a91 zDwbnv07y9C3Z8<`x)8qke&L1b*%SEzZ-7xRT+vNUHH^H(M6qn49{DF_v+{d(nVQs{ z#AGS~PDMnAU|B?agGfo-EiM;VK3F^6icM_diCqXFFUsc_wdX8D`_95F&{U@Zu3tWp zi?4Q{fHkU`x>>C_2Jsnf;@EHoIcuuP^)j*bnr^5}=Z!-(Jg6S&Qxf2eW|sv@^B-?l z1Yi37R7tL4SSs&T;D8J+^*)AFEJkXSRl8~Rs$3wi(~9aC&=pXt(}gqtE7WDd1LM$2 z2|Q?$gQj7$4t&rwbf~HfeH`q(U5fhFOZ`46E77`vIiWh)q;U!BY z)if>czdpNEVqFRSV*BC1E zpXkgE8rwnHZ4})`$~H=Yv4fuPV03g|UX+(E!gG-3#AUx`)_%D=C Bl^y^9 delta 737 zcmYjO|4UO*6u;MZpKkBVN^Lp!tw&nhw0=+tLoyL9P$~)xLKcs;-Tb;Yz3+{hzqrC5 zHVRZ8rT%90i{TFy{?eZiM6fx-*QPKk2nu54Z~jvEYC;Fj=bm#o=bm#u=ehrjtM!8{ z3xLY&nfD{>HUPdd=ScW}#@=IUEG?eD+RYD(vFbT6EXC}xnmITuV@J$35d?r7s{)v* zjKy_$SatIY4*AiQDzLGF$sGVnt~X9dcBXJ1$NwvLG&?hW^2 zeZojgg>RC?IF1@Lq>aV#2-d>pSw3_|qy=j)G@XhqQwztXrx$cEv#%9&K%#Ttdx8rOue@gAp zGX1i`S)$YIlUruXl6PBb%1ceF18b2N*S4g#vdx~km95UeiW7*^e;o>fQgH#^xs5z| zI*PY!vA#5S|3D%(v}LvV!pRLVV}<3*>AH3Mr=tQsVu>Gu;PPESHO z0L)*qf7V0uh>Jpz*OKw66gkZTH4Fj_7|{oGvH!J59IGmE)7UF;(3LP!_idNriCA(H zUnV`&W!KjSC{#EI;V!ta3w*o4Ujp_LkV>GA8WjW_L`Vz2TM>l8y=nz|EBz24DKoRl XHGW3+Y;$I&AhebDPKUSQ9z diff --git a/src/__pycache__/slideshow.cpython-312.pyc b/src/__pycache__/slideshow.cpython-312.pyc index 31b38509a365a7982078f9166b885f41ca3e252b..27ed67c23c762309f7cf0dc2d0cca56d29c223d1 100644 GIT binary patch literal 3527 zcmcImT}&L;6~41G`!};cuwMQ#jEzmQPDARS*0O}G*0|U>Er3Z;jwN@?)Oz(ibDPGMZA=Nz@14T#+hLo_g+`9cFFONKw_h z+I!Bu_uO;tIrlr~&R^nj5kXVGzNCEw+}CvAwNRZodY?yV1HFS(q;h$b<$wnAfdZf9 z3qn@l-1%TO2=jbCR0wCo910*DQ3W-)9dNb$1ZATz7tEzS^*+VXZO$EKC6%K;Zx_=O z!&0uxm-e{rI&-`?fx|f20kgPC4GjVXdtC0UC+|~lXEudXxmWyok5j{*PG+CWz3Q#_ z6sJ6yYzuD5z3#7goM+|xbf^(Es){?(w&3o{w&Avubg8kOxMz>XTWQA~;AMh(sV0?9 z+y$d1HtJNH9}3xSwNp(2Jq`2}&>o;^puH?6Kl9G$(*}Re;4>$k;U#}=`g=VNpHW+I z?@sGB;DxqqAMQIz6Wq#eSE8{8AKPBIcP@9bjdpyx!Nz%f{{LX31NSu8=*Rv4gN<%K za)7tD8hv(oe|?GTLl=?7Ed)3;i8%OGx!=9N$WNjLF4J{L#YZy%Cpc12X0a1yWMV$U zIl^7dB4yDchPgD5vkcwgOh?kF*i=y=b5^;73CrVoO~uxnu^=yKWKN#Ii^M@x<$J%>6&ZlaK$ll0LswFNHE-#2Ow0DZCLa-&1IV`K1 zRm>|(Sd|%IWJOnHdiU~u1uj)KbS5=jGEJ-#S<_X#IKY&QPtResl&`DN>6Q}HE0=Vb zwPY6-t}p=Cq_NSefCs=&kQvKxW(+0|=>wouPQgmENn>e-Y1a&$2V;67%cO{M1fz&` zCuCwvD`S%a$Pvfp3}P^hJ5jALJC#@N7)}*hFBT^Oh1s=fc2&Q2WC#cL2 zY&tRb=u_^ocqc-&(A;4M1fUmYEovQt_g#}^PQPn;sWebrGG$m{9lbc~kI>oZ-w6~+ z>_-ycgiur0Czp4Vz4q+`skOSeE6Mgvn3bB=FRWdt-rEyJv4=o9n0P9rcZKxk0sq_FDUQ#eR2xboI{4oeKH*-MdLrO#TS`wjB ztTh%cz*eAqnZaVhn4R@N!4M!@1i&U6GYm+6+?X`Q1-o$>bbgA=b3n{K=$sf~ir^BU zxR~^zz6O7brj?Dp5mBnWlC_8bDK#HN(jO(B^C*^LyI*jNqJz102be~;RE{Ouu`_-O zZr8s?SfU|9k;qzuyMYW}{wX`YqCQacX_^8C^NwYKn@5_PI4}8Y(sDBTsldQ(o`!+h zN;{c${j~EVAX05EBFzi1Gz9-6n)u*;s?d|wdE40ZQqpQ(bn&-AnEE|qzWb~G+!X>d>;tD6Ai(Bk2Qr;S1ZsusLs zf(7pzdz%(ZH0i%ue=Ltt{K#*}U;W`Tc?=3&IXp^B)%EKj4@HEOOno%-suL#jnocW0 zfXqAm*vMU0Y~1o9us1bCmWrA_YX<3Q+Nfn=M$3b_yrHP<7J-F_*b(OOlEq4x!&}63 zl2cQPt{adAnxR`$Q%+!F-t3_YfC;HS3V?#Gegur(|gig_r!Z*S%h9_JRmQn5!MVJ#QD4L!( zjN;3e5g9BPw8CFE-vl!>FRb4{|D5MI?f|9#fqMRiq`#xKFN4v_k2d*QuzO3`Pjyw# zZDby0HgEp^4g1Y+c@#SRuL$bw*_?mcGqBq;u-EhBy^f2vRGFyutxfKsi_b$S61UCO z(n{%r1zXrh!m79;K9Txs=oMItw^VMd-(I_2o%rpj9o^Xs1v)#A5paUY4R$(3aFZ97>*?a!o`&D-N2#P*YEJ5&+&Q2I#d=K78XBV5~2 zI?SCqN(|zuTaRvSowecM=NlDHJ{D`z(8&tFM6rhn8V#`YVe;Ew b2OyHW!S3%Y2`=JKr-rZaUt9?eUl0EW2hrCl delta 1554 zcmcIj&2Jk;6rb^a*xt3*an@gnliG=i!KtW_+6dITNL8AsMg7QusKQu^Om^yeW5;H8 zP2yg%6^OP6gw22|pkVZ;DS^H2QFAaB65S^U{uiyR=DK?GwZlGGzTv1YJYm~ z>GwWi3k@s0PZzjoLF!GBx;<-Hyw-szzoPZX-v?E zdj23HXA}1Pj9Y{3?Pozib0p-}!;J?Cr-wRFA8kAsy_8XqqQ?e{^lVM&m$Fl#9)FgD zls+fpM}B>Zyap#Wj^t^g=G0tU?k3->l2MVWPd!^vleXl3O$aoQ3uvBPQ1iYAG9gW& z7}k6gBiazf5nIKn!&L&z9T+T%q6dS$a+qlIqM9F#Yz;T*ve}avN8?A0MVFQCF$R$i zs~*}f)Q|2FK;f<7ji*gwDE2=z38Kh=kT{C}tH&98^#7|ZY2Q2|K#+hQeGHIUYp3#D8hEmd;n z4WrE!v~}{iI0uKw6EVHPl4z`yH`sZ`Et@p7 zS}37BTFn}GIcpRP8ZvH_*G^PwnB4~(!qhN6qF{mFoZcOm((#SnKiTrdtP8txsJ`Bk zTti!Ccp`1Pf}=m%yK?oWD==hoTQ;?`WYb#7U=lHcQV%e&$55l75G5ua=Og zhj=#LL5s^_fM1|4PB9oLMe0%@Hp7C)8L*U_aylJf!04SqxoS|w5_u?{g_Fc1PcC7m zsLfw56j7TmmUEgtATzEc zp3bKm#Yys&eC^c0bdEj6*NPHihmOYVxm<+bqb>aFU#YZku)_}kJg=?6LaBY6H-Pk;=0!wzqdJoHS) zM5o2=xD`v>*zwx9F!@3d5e5Jp37sMYN8*GJ{V zjD|fPM?IO?VHE6i!$Z2myoi2S!8v?l`S4uPS*vIb2|Um++5!%ctYdu(4R9^@?6*Z= zZBjZs&D<;a9HCheT`#GR`knO>Dy_WU9&b<9&Ya4*u`bL g6Jyf!;Bax>~MqyQn3EQ2zGAww}^ITIs8Bv3U_JwpX^Btto) zCYRsj3g)iK%q+@`T$9yVR3&e5wZZ+~Up5O^;8@%t?*UOUzB39L8dyX6|ei z6Iz^FR2<_NukF7nCEsJzUl+2DRdNPdF+0+tK>s*|Nz z6NUJ0ag^kzr None: + """ + Sends an asynchronous POST request to the specified URL with the given data. + + Args: + session (aiohttp.ClientSession): The aiohttp session to use for the request. + url (str): The URL to send the request to. + data (Dict[str, Any]): The JSON data to include in the request body. + """ async with session.post(url, json=data) as response: print(f"Sent request to {url}") async def periodic_requests(url: str, data: Dict[str, Any], interval: int, count: int) -> None: + """ + Sends periodic asynchronous requests to a specified URL. + + Args: + url (str): The URL to send requests to. + data (Dict[str, Any]): The data to send with each request. + interval (int): The time interval (in seconds) between requests. + count (int): The total number of requests to send. + """ async with aiohttp.ClientSession() as session: for _ in range(count): - asyncio.create_task(send_request(session, url, data)) # Fire and forget - await asyncio.sleep(interval) # Wait before sending the next request + # Schedule the request to be sent immediately (fire and forget) + asyncio.create_task(send_request(session, url, data)) + # Pause execution for the specified interval without blocking the event loop + await asyncio.sleep(interval) url = "https://api.example.com/endpoint" data = {"key": "value"} -interval = 5 # Seconds between requests -count = 10 # Number of requests +interval = 5 +count = 10 asyncio.run(periodic_requests(url, data, interval, count)) \ No newline at end of file diff --git a/src/main.py b/src/main.py index df445d5..51aee01 100644 --- a/src/main.py +++ b/src/main.py @@ -1,4 +1,5 @@ import timeit +# Start the timer to measure the total execution time of the script start = timeit.default_timer() import json import os @@ -6,41 +7,55 @@ import text_to_img import shutil +# Read the story content from a text file with open("story.txt", "r", encoding="utf-8") as f: story = f.read() def clear_story_folder(folder_path: str = "story") -> None: + """ + Clears the specified folder if it exists, or creates it if it doesn't. + + Args: + folder_path (str): The path to the folder. Defaults to "story". + """ + # Check if the folder already exists if os.path.exists(folder_path): + # Remove the folder and all its contents shutil.rmtree(folder_path) + # Create a new, empty folder os.makedirs(folder_path) +# Prepare the output directory for images clear_story_folder() + +# Split the story into distinct scenes using semantic similarity +# The threshold 0.7 determines how similar sentences must be to remain in the same scene scenes = scene_split.main(story,0.7) print("Scenes splitted successfully!") -# print(scenes) -# for i in scenes: -# print(i[0]) -# Scenes to prompt -# print(scenes) number_of_scenes = len(scenes) print(f"Number of scenes: {number_of_scenes}") print("\n") +# Prompt the user for the desired artistic style image_type = input("Enter the type of image you want to generate (realistic, cartoon, abstract): ") print("\n") +# Iterate through each scene to generate a corresponding image for i, scene in enumerate(scenes, 1): + # Construct the prompt for image generation, including the user's chosen style prompt = f"Make a {image_type} image of" + scene - # print(prompt) + # Call the image generation function text_to_img.main(prompt, f"story/image-{i}") -# Folder and File name generation +# Create a dictionary mapping image filenames to their corresponding scene text story_dict = {f"story/image-{i}.png": line for i, line in enumerate(scenes, 1)} +# Save the mapping to a JSON file for use in the slideshow with open("story.json", "w") as f: json.dump(story_dict, f, indent=4) +# Stop the timer and print the total execution time end = timeit.default_timer() print(f"Time taken: {end-start} seconds") diff --git a/src/scene_split.py b/src/scene_split.py index 8ea4ead..0805f43 100644 --- a/src/scene_split.py +++ b/src/scene_split.py @@ -10,9 +10,28 @@ story_text: str = """John walked into the forest. He heard rustling behind him. The trees loomed tall as he pressed forward, his heart pounding. Later that night, he found a small cabin. It looked abandoned, but the door creaked open when he pushed it. The wind howled outside as he stepped in. Inside the cabin, an old man sat by the fire. He wore a long cloak and stared at John as if expecting him. In the morning, John woke up to find the man missing. The fire had gone cold. He stepped outside and saw footprints leading into the misty woods. With no other choice, he followed the footprints. The deeper he went, the more uneasy he felt, as if someone—or something—was watching him.""" def split_into_sentences(text: str) -> List[str]: + """ + Splits a given text into a list of sentences based on punctuation. + + Args: + text (str): The input text to split. + + Returns: + List[str]: A list of sentences found in the text. + """ return re.findall(r"[^.!?]+", text) def main(story_text: str, threshold: float = 0.5) -> List[str]: + """ + Splits the story text into meaningful scenes using semantic similarity. + + Args: + story_text (str): The full text of the story. + threshold (float): The similarity threshold for merging sentences. Defaults to 0.5. + + Returns: + List[str]: A list of merged sentences representing scenes. + """ index_name = "text-search" sentences = split_into_sentences(story_text) @@ -24,26 +43,39 @@ def main(story_text: str, threshold: float = 0.5) -> List[str]: pc = Pinecone(api_key=api_key) index = pc.Index(index_name) + # Load the SentenceTransformer model for generating text embeddings model = SentenceTransformer("all-MiniLM-L6-v2") + # Generate embeddings for all sentences at once embeddings = model.encode(sentences) merged_sentences = [] similarity_array = [] i = 0 + # Iterate through sentences to determine if they should be merged while i < len(sentences) - 1: + # Get embeddings for current and next sentence vector_1, vector_2 = embeddings[i], embeddings[i + 1] + + # Example of querying Pinecone index (if used in future) response = index.query(vector=vector_1.tolist(), top_k=1, include_values=True) + + # Calculate Cosine Similarity between the two sentence vectors + # Formula: (A . B) / (||A|| * ||B||) similarity = np.dot(vector_1, vector_2) / (np.linalg.norm(vector_1) * np.linalg.norm(vector_2)) + similarity_array.append([similarity,sentences[i],sentences[i+1]]) + + # If sentences are similar enough, merge them into one scene if similarity >= threshold: sentences[i + 1] = sentences[i] + ". " + sentences[i + 1] else: + # Otherwise, the current sentence is a complete scene merged_sentences.append(sentences[i]) i += 1 + # Append the last sentence/scene merged_sentences.append(sentences[-1]) - # print("Similarity array:", similarity_array) return merged_sentences if __name__ == "__main__": diff --git a/src/slideshow.py b/src/slideshow.py index c8c676d..a9ae93e 100644 --- a/src/slideshow.py +++ b/src/slideshow.py @@ -6,15 +6,18 @@ with open("story.json", 'r') as file: image_texts = json.load(file) +# Iterate through keys to get image paths image_paths: List[str] = list(image_texts.keys()) -# print(image_texts) +# Initialize the main window for the application root = tk.Tk() root.title("Image Slideshow with Text") +# Label widget to display the image img_label = tk.Label(root) img_label.pack() +# Label widget to display the text, with wrapping text_label = tk.Label(root, text="", font=("Arial", 14), wraplength=600) text_label.pack(pady=10) @@ -22,40 +25,64 @@ paused: bool = False def update_image() -> None: + """ + Updates the displayed image and text based on the current index. + Schedules the next update unless paused. + """ global idx, paused + # If paused, do not update the image if paused: return + # Retrieve current image path and text img_path = image_paths[idx] text = image_texts[img_path] + # Open and resize the image for display img = Image.open(img_path) img = img.resize((600, 400)) img = ImageTk.PhotoImage(img) + # Update the labels img_label.config(image=img) - img_label.image = img + img_label.image = img # Keep a reference to prevent garbage collection text_label.config(text=text) + # Move to the next index (looping back to 0 if at end) idx = (idx + 1) % len(image_texts) + + # Schedule this function to run again after 5000ms (5 seconds) root.after(5000, update_image) def toggle_pause() -> None: + """ + Toggles the pause state of the slideshow. + """ global paused paused = not paused + # If unpausing, immediately update to resume the cycle if not paused: update_image() def next_image() -> None: + """ + advances to the next image in the slideshow. + """ global idx + # Increment index with wrap-around idx = (idx + 1) % len(image_texts) update_image() def prev_image() -> None: + """ + Moves to the previous image in the slideshow. + """ global idx + # Decrement index with wrap-around idx = (idx - 1) % len(image_texts) update_image() +# Frame to hold control buttons btn_frame = tk.Frame(root) btn_frame.pack() diff --git a/src/text_to_img.py b/src/text_to_img.py index d6afb87..6c2d29f 100644 --- a/src/text_to_img.py +++ b/src/text_to_img.py @@ -11,6 +11,14 @@ client = Together(api_key=TOGETHER_API_KEY) def main(myprompt: str, img_file_name: str): + """ + Generates an image from a prompt using the Together AI API and saves it to a file. + + Args: + myprompt (str): The text prompt for scanning content. + img_file_name (str): The base name for the output image file (without extension). + """ + # Call the Together AI API to generate an image response = client.images.generate( prompt=myprompt, model="black-forest-labs/FLUX.1-schnell-Free", @@ -18,16 +26,19 @@ def main(myprompt: str, img_file_name: str): height=768, steps=1, n=1, - response_format="b64_json", + response_format="b64_json", # Request the image as a Base64 encoded string ) - # print(response.data[0].b64_json) + + # Extract the Base64 string from the response imgstring: str = response.data[0].b64_json + + # Decode the Base64 string into binary image data imgdata: bytes = base64.b64decode(imgstring) + + # Construct the filename and save the binary data filename: str = f'{img_file_name}.png' with open(filename, 'wb') as f: f.write(imgdata) - # image = Image.open(filename) - # image.show() if __name__=="__main__": main("Cat eating burger", "burger-cat") \ No newline at end of file