From baee58c2a9974c4a191a2ce5299d67e71fcb817b Mon Sep 17 00:00:00 2001 From: "nisch.codes" Date: Sat, 15 Mar 2025 20:20:41 +0100 Subject: [PATCH] Initial Code commit --- README.md | 30 +++++- image/README.md | 14 +++ image/compare/README.md | 21 +++++ image/compare/compare.js | 80 ++++++++++++++++ image/compare/diff/.gitkeep | 0 image/compare/new/.gitkeep | 0 image/compare/new/image-01.jpg | Bin 0 -> 9976 bytes image/compare/new/image-02.jpg | Bin 0 -> 8878 bytes image/compare/new/image-03.jpg | Bin 0 -> 10516 bytes image/compare/org/.gitkeep | 0 image/compare/org/image-01.jpg | Bin 0 -> 9761 bytes image/compare/org/image-02.jpg | Bin 0 -> 9752 bytes image/create-placeholder-simple/README.md | 21 +++++ .../create-placeholder-simple.js | 89 ++++++++++++++++++ .../create-placeholder-simple/placeholder.jpg | Bin 0 -> 9761 bytes .../create-placeholder-simple/placeholder.png | Bin 0 -> 3130 bytes package-lock.json | 88 +++++++++++++++++ package.json | 29 ++++++ 18 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 image/README.md create mode 100644 image/compare/README.md create mode 100644 image/compare/compare.js create mode 100644 image/compare/diff/.gitkeep create mode 100644 image/compare/new/.gitkeep create mode 100644 image/compare/new/image-01.jpg create mode 100644 image/compare/new/image-02.jpg create mode 100644 image/compare/new/image-03.jpg create mode 100644 image/compare/org/.gitkeep create mode 100644 image/compare/org/image-01.jpg create mode 100644 image/compare/org/image-02.jpg create mode 100644 image/create-placeholder-simple/README.md create mode 100644 image/create-placeholder-simple/create-placeholder-simple.js create mode 100644 image/create-placeholder-simple/placeholder.jpg create mode 100644 image/create-placeholder-simple/placeholder.png create mode 100644 package-lock.json create mode 100644 package.json diff --git a/README.md b/README.md index 6dc80ef..f90c7ce 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,31 @@ # web-helper +A collection of little node.js scripts, I have created over the time. Hopefully this helps you. +I try to comment the code as much as possible, if you have any questions or suggestions, feel free to leave a comment here in the issue section and I try to answer as much as possible. -A collection of node.js scripts to help on every day webdev problems \ No newline at end of file +## [1. Image Helpers](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image) +A collection of utilities and helper utilities to work with images.
+[Go to Image Helpers](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image) + +### [1.1 Compare Images Helper](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image/compare) +This is a little tool to compare images in two different folders, to determine if they are the same or not.
+[Go to Compare Images Helper](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image/compare) + +### [1.2 Create Placeholder Helper (Simple Version)](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image/create-placeholder-simple) +This is a little tool, which copies a placeholder image for an array of strings containing the new filename. This is the simple version with no other dependencies, there is also an advanced version using an excel file.
+[Go to Create Placeholder Helper (Simple Version)](https://projects.nisch.codes/nischcodes/web-helper/src/branch/main/image/create-placeholder-simple) + +
+
+
+ +# FAQ +The following questions are some of the most common questions and I wanted to provide some explaination before hand. + +## 1. Why do most tools use the sync version of a node function instead of the async version? +Naturally you want to use the async version of the node function because you can distribute heavy workloads more efficient. However if you work with a compare function or a copy function, you most likely want to know if something happened before the program completes. In this case it is better to use the sync version of the node function, so the program continues after the function completes. Don't get me wrong, I love promises and async functions, but often times it is better to wait for them to complete. + +
+
+
+ +## MORE COMING SOON diff --git a/image/README.md b/image/README.md new file mode 100644 index 0000000..0af4797 --- /dev/null +++ b/image/README.md @@ -0,0 +1,14 @@ +# web-helper -> Image Helper +A collection of utilities and helper utilities to work with images. + +## [1. Compare Images Helper](https://github.com/nikolas-schwarz/web-helper/tree/main/image/compare) +This is a little tool to compare images in two different folders, to determine if they are the same or not.
+[Go to Compare Images Helper](https://github.com/nikolas-schwarz/web-helper/tree/main/image/compare) + +## [2. Create Placeholder Helper (Simple Version)](https://github.com/nikolas-schwarz/web-helper/tree/main/image/create-placeholder-simple) +This is a little tool, which copies a placeholder image for an array of strings containing the new filename. This is the simple version with no other dependencies, there is also an advanced version using an excel file.
+[Go to Create Placeholder Helper (Simple Version)](https://github.com/nikolas-schwarz/web-helper/tree/main/image/create-placeholder-simple) + +  +## License +[MIT License](https://github.com/nikolas-schwarz/web-helper/blob/main/LICENSE) \ No newline at end of file diff --git a/image/compare/README.md b/image/compare/README.md new file mode 100644 index 0000000..f4ff24b --- /dev/null +++ b/image/compare/README.md @@ -0,0 +1,21 @@ +# web-helper -> Image Helper -> Compare Images Helper +This is a little tool to compare images in two different folders, to determine if they are the same or not. + +## Setup +Befor you can run this node program, you have to install the 'img-diff-js' package from https://github.com/reg-viz/img-diff-js. +Simply type `npm install img-diff-js` into your console. + +## Versions +This node programm is created with **node** version `11.15.0` and the **img-diff-js** version `0.5.0`. + +## Tested versions +I can not guaranty that the program is working with a newer version. Please feel free to check for compatibility or add an issue to the github reposity, if you have any problems. + +| Dependency | Version | +| ------------- | ---------:| +| Node | 11.15.0 | +| img-diff-js | 0.5.0 | + +  +## License +[MIT License](https://github.com/nikolas-schwarz/web-helper/blob/main/LICENSE) \ No newline at end of file diff --git a/image/compare/compare.js b/image/compare/compare.js new file mode 100644 index 0000000..03056d9 --- /dev/null +++ b/image/compare/compare.js @@ -0,0 +1,80 @@ +'use strict'; +// load node standard libraries for filesystem, path and utils +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +// install node package from https://github.com/reg-viz/img-diff-js +const { imgDiff } = require("img-diff-js"); +// create log file for our log function, the falg 'w' helps us to overwrite the log every time we run the script (Use 'a' if you want to keep the log file) +let logFile = fs.createWriteStream('log.txt', { flags: 'w' }); +// create log function to log infos, without spamming the console output +function log(message) { + logFile.write(util.format.apply(null, arguments) + '\n'); +} +// get the current directory and create path for the +const scriptDir = __dirname; +const newFolder = `${path.join(scriptDir, '/new')}`; +const orgFolder = `${path.join(scriptDir, '/org/')}`; +const diffFolder = `${path.join(scriptDir, '/diff/')}`; +// create some temporary variables for statistics at the end +let numberOfImages = 0; +let numberOfDifferentFiles = 0; +let numberOfSameFiles = 0; +let numberOfUnknownFiles = 0; +// async function to work with the await statement for image diff +async function main() { + // let the user know the tests are running (going via the process stdout helps us writing the start notification and the end notification in the same line) + process.stdout.write('\nStart Tests...'); + // read all files from the new folder + let files = fs.readdirSync(newFolder); + // check every file from the new folder + for(let index = 0; index < files.length; index++) { + // temporary variable for file + let file = files[index]; + // create strings with the full path for the files to compare + let fileFromNewToCheck = `${path.join(newFolder, file)}`; + let fileFromOrgToCheck = `${path.join(orgFolder, file)}`; + // create string with the full path for the file containing the differences between the two files + let fileForDif = `${path.join(diffFolder, file)}`; + // check if the file exist in the old folder + if (fs.existsSync(fileFromOrgToCheck)) { + // if the file exists in the old folder, check if the files are the same + const result = await imgDiff({ + actualFilename: fileFromNewToCheck, + expectedFilename: fileFromOrgToCheck, + diffFilename: fileForDif, + generateOnlyDiffFile: true, + }); + // check if the result is the same image + if(result.imagesAreSame) { + // if yes, increment the numer of same images + numberOfSameFiles++; + } else { + // if not, increment the numer of different images + numberOfDifferentFiles++; + } + // log the name for the same existing image + log('Tested: ' + fileFromOrgToCheck); + // log the result for debugging + log(JSON.stringify(result)); + } else { + // log the unknowm file + log('Unknown: ' + fileFromOrgToCheck); + // increment the number of unknowm files + numberOfUnknownFiles++; + } + // increment the number of images + numberOfImages++; + } + // let the user know the tests are finished (going via the process stdout helps us writing the start notification and the end notification in the same line) + process.stdout.write('finished\n\n'); + // printing some statistics + console.log('Number of images: ' + numberOfImages); + console.log('Number of diff images: ' + numberOfDifferentFiles); + console.log('Number of same images: ' + numberOfSameFiles); + console.log('Number of unknowm images: ' + numberOfUnknownFiles); + // only for cosmetic + process.stdout.write('\n'); +} +// run the async function +main(); \ No newline at end of file diff --git a/image/compare/diff/.gitkeep b/image/compare/diff/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/image/compare/new/.gitkeep b/image/compare/new/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/image/compare/new/image-01.jpg b/image/compare/new/image-01.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7c704f10fab86cbf88a2514946347ab46842bbfe GIT binary patch literal 9976 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 literal 0 HcmV?d00001 diff --git a/image/compare/new/image-02.jpg b/image/compare/new/image-02.jpg new file mode 100644 index 0000000000000000000000000000000000000000..51fed6b2c6ebd48e643559c5b6f0bbd347198d4b GIT binary patch literal 8878 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 literal 0 HcmV?d00001 diff --git a/image/compare/org/.gitkeep b/image/compare/org/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/image/compare/org/image-01.jpg b/image/compare/org/image-01.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ac7983a722e3f84642a5339fc90cee79929e64c GIT binary patch literal 9761 zcmeHtbyQSezxSa*q(cFb2I)o`haS2`90Vi>L>i=18YzjPV?bI!Is}FWm2O0l4nd^* z9Z;X2cfId_&wAc<*IjoX*zw)p{CxLepK~^slb2rsLM3^yJb;1%04T@{xSRok08C`T z!osxBn9{cBvoW(Rg4Ub zyu99^{JRP+5daZ3sy-Sm8VWstN`!(&gmT#d+(9~shH_PaKLrC53mpv=1^aRu!2U(P zDEu?`zwN(+09pWU%x`&=DT!%hSMpxM+txp%Q_H4vKLFsjdhnY9kTl$11%Ml!*nbEp zKJSp-k92+n(dEBsDo{TF;3J?VNIAUa60*lEh9H^KMzlQL4?RlJ^DaR#`XO0TpeBY@ z7anzYoQR5)z|ac-FojTd4Hv|o8Rg292fGPcFZNb%TU!e5L_aB+Pm;fTvhKg@b4uE0 z-#o3rY}1N|^cqtLZMm_Vw{(%$u!ehZ?9_TsaDA*d-ezv}lg+~25p#9{LW%t`w91u% zSig}an*>#nq|QJy+@<4%Kd+$^dWAr;f_H1i&}eP^S=5@ z@NbVpIu%*&N3ZmJt@Rf4nQq4OsCG1)KCI?XIqI&O0(GYBTmdxYbk}_k_^*Ni^&O(V zS-u%w-7cYNtC6o1dw1IgPCC8%i{mAvB{{tHW9BLY5!lQpFN9fQo&ZzG6q*_zm+eIR zqRc!!Z+bLTfAB`BD6cAs%LV#Qc-Q+@v*vnC(U*7ZRSnq-F1_N@W+|8nIftz0CeRs7WBT62g=CDM_uRne}ywqA!7*n_s*-1*t$9OojXackC5K~3-3*d^eel&&_i6?$+Oo>{EwmgUVHzBkdp zOg^z5vbrCYUi2dRdT~Q<0$$#J$e54?)kqb&2p?tnU5}6zca1#~wz->s#^}q@CrFMR z`4XQ$B!U^v?M>vs;lVEQUino{S2MQ$^#8a0cMw2BZab97jpb_F`Ag5$wu6Ftz3HG5 z{zd-}b>$F`o3B-)tJ!}3l7(CX$U^UgKT~FFJ?MQs@>*y*pWrz6uJyYbQY<~*dXAN= z8Gk(|K0wE*izlh`dth_oTyWhb$jrKK|C7}ffK*oiA|d?C4iZ2VRCKg!1kwIKAgH9O zQ+I71y(W78$I97tAIFxzTV<%|`0|%y_%m2vx>Z~5C0zT1CjD;zW!jMik>AxUmgvnT zz0WYYYfj|g!jkm5i&m>~-To)5D+qa!K4GFFA;Un!_`MQQP|?saFp*DXg2ZIB0wjF= z4>Wk>j7jO}nRv^ke?JeQU;~#x&zvqCyJc#{v5VM3HN)WW5)d=?^|IcHW~4Y zm|_ia$yU8h8caFuhS(;KF4VYFZ5OI`@gvIxw!E2{`NKF#MBHqCn(gxNf{|k$6S_rl zv96jYB6^-QvCr=kcnQ@am4%*0Ci)^?X~v$hQb!mKryH$tLZwxe5(MpF@E~xpSudOPa8+FVS|C`+>4tl$(x|mwu2wZ=LcwUM z?4&x#Ys#acNH?VO2ubmzs(>aL^33s@EkNz7*)=6=WHD$n0x{MGs8rUkq%h^>%@}y< zxoi3a*)wcuxdbo<#|57*s5Tf}*+Np0GA0k1 zo2FULi6$W-Gv?Pm{Gv-{Krn}En^m}5ca_hG$6qs!7CMfeG~D84W_{@_z{w6~m5ek5 zvvm^ft23L)6v-=@xkjwLyqNEdE{Am(+0sO|tRrqmyFBFbmJ3%3H5!pkYJ(B3$Br=+ z$+aDoGSlSTud_^h+sL7z*O}%BKA2Hft(jKPc~wZQ#kT;e$8BGQ7X%knFeUTTQ!8Eq zUsF*9mg8m)G-skDW$-R2Y?O$tb?U9X4Y4(KkMklNK2(I$+ssEa43}2=uwuuPA{r>k z6X35iRW0p8x}ZNnE4b(F5i}g~NDN z*t4^t24L`>p6ij9MJD52`<7W@cX;U=O1*b_gmKcuum47ZpPMxlq83PQBRg~QQGeXJ zb6-|bMPSj1D`Yili(-X+tN(VAI_X^Y_~5rY&-PO)O2)$UzuP!4iB82Po$qP5hNh_n zbu7n?e9)NS`AKaPk+H`8qu4+rUMsI(dwmu1b$#uHT$j~K`0=+r+2nk(!NIChM)>Zd znfaX*uNZg4C15{4p*6x)SNgs{sHznE(apcIw1yoe5;9RchWEZeuE!YcezUrB!Zr1e zU*EWt4Mz2-^uFi_on*~~I#iW1@ShAeUjaq3((N}4@el%`%9K{V;_`&IAU?c)Gj8@I zQo`p>Fb#$1ncK*~2&QIbCHTL%@~wMP2j*aH2_wDA8bNOI+Hn2%r}Uvzv0mC zFhTAU%B#8*7oF%xMQ&hQW$XIQ1zxxq;2BCD_ti_?zj`Lbk?NMgV{5#{8Y^jy$A)$3 zrp%5pcGBtexLq4!hIP~5+h8zQn#~4w30-1MqeJyfRN3s6mZsj1*#swq@1%!wroVSh zJZDz*F#STdD&%NP6^tAT{brSjeIz+k`gVl;q>CM|a(v=B3*=+kFr|;!mV!5a?X@<= zn8lD;mjMJPj)5v$5|Ijfp$9(XomsM!tRnK(QpHvx1}kO{(jhw5uT>^9z z31?I3IOvMPNBM%@_N*(!jz*^3(f`;XWW}B>r5|E=?JT`FBTJ5G=uZl5f~LL}>?$Ux zKoLZar!22aLMK(3k>_2v)yL=n?)9^>-pQqoe?g*ty9LTC!X`}IE4=6)rO&F4d-q_Q z!ft>djel0<8{=d2S)uvJmIhkAgH=s2U7^7ClU zyF3l#!byv!!qfyQwMjCx5thE5k>ww`Wq%CQ7$gU~ooDEGTtJ(o_S2Uer{pL^V0!R= za?LcBla@WB+XHTv5e4zHRdM+lviUk-=h56tpl;|A$a_#JJ!Z%e8(F~$vrF9)olz7l zYlG?>hpW%)1(h-iisnQIE8R9RaU=HGR~4<8 z&L&H9y{3Mynws>-HfMZ;3Gm@U2jrjpB;J38AQ@>?m7F5Cba1EpWOK(|Wk0skHiL;r zwVSaca$}=iqT>_o;lYdF{&Rj65ycUh`lgLqA<`?I_@diAx-&zJ&8!xlwZj_l33jq4 z^oBQMJl1k1KT`WkOUI{+!&|SnCrcA*ji@zEco5sagK;BEe9mf&6hWZH&@e;F4m9OD zFb0AXQ}at*n?oKuTmm^qU7n5Nk4)n%R6LZ_iIX|j@0KZBEDQLqX>c~04TYW7iyOF! zTmoJv;sm16!v@4vDY|ULll+?4F^M~IuY;Iy7~hOM@>s-_ykXQw?H-aMN!Wrqn8Sep z-;(~PN{68C67aV4N3O`D$u@I4t4-aoB>BuJ- zjuxR^F#2NW73r)rDJyBj(W}ok%-9L#f3E8KVxr{88XF6v`611~PtW$j;czsGv1;a7 zP2%)vuZzpilhn6QpV8>vFL-ZxA)4l2*hBf>xQgiTT^wgds6_Qt+td5TOC3{P0?0>y zDMA1R4HXpw8wV8w9qsBx0|og>6fF*&keH5FQ=5bqq!n9H*+ws|p=09Uj~L>4z;A4t zJ&(cXSWYUF^ZP{rM+*5OP%zgh6H*|-;)?Oo^MZ@6CE=yzSVsw`SU6&&?tgB>&P8Ve zX={dy{V1-gI|!N37Y!`&0?G?R;G%Jx;{NNJ&3Bs(PYe}@$10uS)w*kpuE zpmH+<>a8nLLrhYrcxyb03ML)K4tu&#&1OE)W)ye zP%?-TPconT4xd(jl|neq*K(0GPGDR-+7DmPB zR)B`?pNNS>Svnl?X(eTEuLe!mGLO{@{#@yLCz_jj9XCB@zWb6W7ZiF-gj4-owb+qh z_zn2evj&$cVnT-0`U{Q}XM^u_n1XFM)dI=pm1`9HXCW1efGv}v@uc_w|9I9}v(ht~ zvjM(;qP6@h+H`V(x~@s9*L?@keUo3YPnHmF9$#DfB`dTHy21WTe9gH(VNZsRRg3d? z(ZE^wXGdkr4pd(@086X9?YDU_+UlT+V!uZaM(_3!^%MA8B>A{Xtv%ZN7=# zPg4|CS@Q(^;hwL&9y$p}Z4U%>;9OD42>S~zp06BLE*z6}Tt_Uln!LHhUD?KwlSof9K1&i@^or#*4*i z#Lw*@rRi_r<9P9*RkV_0Cu()MD7*fu?yrEw^5*IDejwHn>60u*Izrz^Dj-#4am1bb7&r?|aofOxPUUm%wsm9N0soy{pvrY%9Q-H%X zB>KMimzQ+l*U4S|R0VM>vPGO;f+>8=Oi1790AWAL`gztQN);|fXT+5ir1$Bf2Ell)r=5*bT}C!HSAg1g9K)VHzvy>5d$)eSg^jFT>L(5tr)#9z)aN9W^d)M`SsoJIdGxlSCu@tcbz-9#w5Q54cRM(&>tyJUKoz z+t!>R=wKl>K1`_35Gwt!+h69n`&Ii#kowNl?4tV4#aO$W<9Z_-*(~BQz6}JlC%-ry z$*72rk$a^LN3`0N0c-m?4B zgv9X=)+6b|U^fwmKOuKWRKNuwraF7*=gc)RP#*bumN#7N@!6%s3pJ=EkROau#A1l& z2?|!Nqe8-WU(;C;9$>sJ$ZZP~!WoY7bBBkP4d_K5jGN%`09z5u! zW8y4qRVm$8t^A^Xzo_!U5}mp7UK3;+0T9vQEv!IqAw${uQw;Iw+oV=+G@BwWRnZ^5NLtrqg3 zXpWs47s&6Ox~~Wr@hHY<1Uns(d$G@aQj_iu%@>ci4CNOw=+s$R%A(YbD=~Dbhi5SW z-UECW%qD1(4Q~xOS>S8a6h((IdVUgoOiAUN{fQJw9Q<7R76RfZa2(z;UFH^KiaVs+ z`4(H1t)Z)*O5fq$>`&ks9>;9uA6A0XZW5bo+3f9EsK_cI6$P93Us*=nrUE{7zBCy$ezrz!Pxsphk3c+a{Jog+ z64!_aaSLx{uVa7|1X~fiP{8zEn^0BaYdQFFm3tKRKGiUukgrGHS z641(^g!Y(JFKzfuN!Xl6HUJO;t27P9PS^n>HRIW@)JOU?3Y~BcT`{Fj?W&Uhv5lcrE?ECf%hy4wV;#yn z65eIsrS|XmB42d)hyYX+G!%5?f1dn4PPsnfAOeUFD`1wMfZ$K_)T$4o?2D zmGi&O-%wDbfK#v8tG?|%>s1Yk4JzM^t% zl(7q094_Bt;V(*o6%Ir>m&QyeNG+q4I-AY3V!rTuJRW2NTLhq|R$ALcabJL!$NY@Ek10 z5>F;c*s*>8epI1h5iLbf#*aOc{=z%C#RQ?W(K8QIyPMnqc@0{|$Q8zYt>KTle4WIJ zt`dQI#b&PS-hQs><%UfIH_i35N>I>^1B<_h73vQF%&49Ux#HD!2foh&eUBcS+WnkR z{8&ERSwFk&8vJSdE=`%Bva+B~KdI8A$pbutQjMAU)^?@#_h%va|I)PdaxHm44UX_( z-(kJ5PE7PD)Vrtgj{0wAB3<220L5weRUUbNpHRiPpjSnBj5TW)GxgHW>1qHDG97JL z!PBMM5a!mtjyE+IfjXmuBhnSJ*_sL(V~Z9OkIobzNfh;&_w;v-IG(~O!yUpx+`W8G zXahj#g!Z6$t46irG&BEnZEZPKR2kxV9Vf^`>wpq(W8d8}aK80A%^JDXyMew2#oWXU zXFwnobhdN)qn~WYIsv*OoQ&VQZq>TafFzAV` yj}`=E`z3p&F4BC_)z#2K41bu{vEFb=nHN&iW0DBkm-Lc@rBbP=NzrFsPW>M(qwCiI literal 0 HcmV?d00001 diff --git a/image/compare/org/image-02.jpg b/image/compare/org/image-02.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7eee2ea4c7e6fd57f0d6219a81020f314408a8c0 GIT binary patch literal 9752 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 m#;tJ7>ecXjP0mB#yAnsT Image Helper -> Create Placeholder Helper (Simple Version) +This is a little tool, which copies a placeholder image for an array of strings containing the new filename. This is the simple version with no other dependencies, there is also an advanced version using an excel file. + +## Setup +No other node package necessary. + +## Versions +This node programm is created with **node** version `11.15.0`. + +## Tested versions +I can not guaranty that the program is working with a newer version. Please feel free to check for compatibility or add an issue to the github reposity, if you have any problems. + +| Dependency | Version | +| ------------- | ---------:| +| Node | 11.15.0 | + +  +## License +[MIT License](https://github.com/nikolas-schwarz/web-helper/blob/main/LICENSE) + +Font used in Placeholder Image: https://www.dafont.com/8bit-wonder.font \ No newline at end of file diff --git a/image/create-placeholder-simple/create-placeholder-simple.js b/image/create-placeholder-simple/create-placeholder-simple.js new file mode 100644 index 0000000..a9e56fa --- /dev/null +++ b/image/create-placeholder-simple/create-placeholder-simple.js @@ -0,0 +1,89 @@ +'use strict'; +// load node standard libraries for filesystem, path and utils +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +// create log file for our log function, the falg 'w' helps us to overwrite the log every time we run the script (Use 'a' if you want to keep the log file) +let logFile = fs.createWriteStream('log.txt', { flags: 'w' }); +// create log function to log infos, without spamming the console output +function log(message) { + logFile.write(util.format.apply(null, arguments) + '\n'); +} +// get the current directory and create path for the +const scriptDir = __dirname; +const placeholderJPEG = `${path.join(scriptDir, '/placeholder.jpg')}`; +const placeholderPNG = `${path.join(scriptDir, '/placeholder.png')}`; +const destinationPath = `${path.join(scriptDir, '/placeholder/')}`; +// determine the output format, you can use either 'jpg' or 'png' to specify the fileformat used to generate the placeholder images +const placeholderOutputFormat = 'jpg'; +const placeholderImage = (placeholderOutputFormat === 'jpg') ? placeholderJPEG : placeholderPNG; +// a example list/array of names for the placeholder images. +const listOfPlaceholderFilenames = [ + { filename: 'placeholder1' }, + { filename: 'placeholder2' }, + { filename: 'placeholder3' }, + { filename: 'placeholder4' }, + { filename: 'placeholder5' }, + { filename: 'placeholder6' }, + { filename: 'placeholder7' }, + { filename: 'placeholder8' }, + { filename: 'placeholder9' }, + { filename: 'placeholder10' }, +]; +// create some temporary variables for statistics at the end +let numberOfImages = 0; +let numberOfFailedImages = 0; +// async function to work with the await statement, if needed +async function main() { + // let the user know the gereration of the placeholder images are running (going via the process stdout helps us writing the start notification and the end notification in the same line) + process.stdout.write('\nStart placeholder generation...'); + // check if the destination folder does not exist + if(!fs.existsSync(destinationPath)) { + // if there is no destination folder, we will create on + fs.mkdirSync(destinationPath); + } + // check every file from the new folder + for(let index = 0; index < listOfPlaceholderFilenames.length; index++) { + // temporary variable for file + let entry = listOfPlaceholderFilenames[index]; + // create the full path to the destination folder with the filename + let placeholderImageDestinationPath = `${path.join(destinationPath, `/${entry.filename}.${placeholderOutputFormat}`)}`; + // read the source file into a buffer + try { + let data = fs.readFileSync(placeholderImage); + // next we want to copy the data buffer into the destination path via the base64 operation + try { + fs.writeFileSync(placeholderImageDestinationPath, data, { encoding: "base64", flag: "w" }); + } catch(err) { + // if data is a string we want to log the error + log(`Failed to create Placeholderimage: ${placeholderImageDestinationPath}`); + log(err); + // increment the number of failed images + numberOfFailedImages++; + // and want to continue the loop + continue; + } + } catch(err) { + // if data is a string we want to log the error + log(`Failed to create Placeholderimage: ${placeholderImageDestinationPath}`); + log(err); + // increment the number of failed images + numberOfFailedImages++; + // and want to continue the loop + continue; + } + // log success + log(`Created Placeholderimage: ${placeholderImageDestinationPath}`); + // increment the number of images + numberOfImages++; + } + // let the user know the tests are finished (going via the process stdout helps us writing the start notification and the end notification in the same line) + process.stdout.write('finished\n\n'); + // printing some statistics + console.log('Number of images: ' + numberOfImages); + console.log('Number of failed images: ' + numberOfFailedImages); + // only for cosmetic + process.stdout.write('\n'); +} +// run the async function +main(); \ No newline at end of file diff --git a/image/create-placeholder-simple/placeholder.jpg b/image/create-placeholder-simple/placeholder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ac7983a722e3f84642a5339fc90cee79929e64c GIT binary patch literal 9761 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 literal 0 HcmV?d00001 diff --git a/image/create-placeholder-simple/placeholder.png b/image/create-placeholder-simple/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..01ef2de4f8585f0f6f1f9194bb1a41f82432c783 GIT binary patch literal 3130 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d97dad8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,88 @@ +{ + "name": "web-helper", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mkdirp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.1.tgz", + "integrity": "sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", + "integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==" + }, + "@types/pixelmatch": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.2.tgz", + "integrity": "sha512-ndpfW/H8+SAiI3wt+f8DlHGgB7OeBdgFgBJ6v/1l3SpJ0MCn9wtXFb4mUccMujN5S4DMmAh7MVy1O3WcXrHUKw==", + "requires": { + "@types/node": "*" + } + }, + "@types/pngjs": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@types/pngjs/-/pngjs-3.4.2.tgz", + "integrity": "sha512-LJVPDraJ5YFEnMHnzxTN4psdWz1M61MtaAAWPn3qnDk5fvs7BAmmQ9pd3KPlrdrvozMyne4ktanD4pg0L7x1Pw==", + "requires": { + "@types/node": "*" + } + }, + "decode-tiff": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/decode-tiff/-/decode-tiff-0.2.1.tgz", + "integrity": "sha512-v/7hQBv/DrOVQ+Eljg0BLMRbXZYuuw3YZ8duZuFxYpo6qUkdn7oFRkN95RZKbnh08EHNjrMXMbEUNhTLuhPvvA==" + }, + "img-diff-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/img-diff-js/-/img-diff-js-0.5.0.tgz", + "integrity": "sha512-oaM2kASTy24CCRCc29H7eTAbiDMjTSaP7bcojTjCTMpJcoh5dhtQ+QtLY7xbXgzwQJp/wQAW8rHSCZmijbAvZQ==", + "requires": { + "@types/mkdirp": "^1.0.1", + "@types/node": "^14.11.2", + "@types/pixelmatch": "^5.2.2", + "@types/pngjs": "^3.4.2", + "decode-tiff": "^0.2.0", + "jpeg-js": "^0.4.2", + "mkdirp": "^1.0.4", + "pixelmatch": "^5.2.1", + "pngjs": "^5.0.0" + } + }, + "jpeg-js": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.2.tgz", + "integrity": "sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==" + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "pixelmatch": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", + "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", + "requires": { + "pngjs": "^4.0.1" + }, + "dependencies": { + "pngjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", + "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==" + } + } + }, + "pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..04cc987 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "web-helper", + "description": "A collection of node.js scripts to help on every day webdev problems", + "version": "1.0.0", + "author": "Nikolas Schwarz", + "homepage": "https://evolut.solutions", + "contributors": [ + "Nikolas Schwarz (https://github.com/nikolas-schwarz)" + ], + "dependencies": { + "img-diff-js": "0.5.0" + }, + "devDependencies": { + "img-diff-js": "0.5.0" + }, + "keywords": [ + "nodejs", + "node-js", + "helper", + "helper-tool" + ], + "repository": "https://github.com/nikolas-schwarz/web-helper", + "licenses": [ + { + "type": "MIT", + "url": "http://opensource.org/licenses/MIT" + } + ] +}