From bad6514e68e03428ea47925b4fba3e4840a7ed4e Mon Sep 17 00:00:00 2001 From: r-cemper <146277387+r-cemper@users.noreply.github.com> Date: Fri, 23 Feb 2024 11:04:13 +0100 Subject: [PATCH 1/5] Add files via upload --- Dockerfile | 12 ++ README.md | 27 +++++ demo/demo.jpg | Bin 0 -> 188054 bytes demo/dockerdemo.jpg | Bin 0 -> 188054 bytes dev.md | 117 +++++++++++++++++++ docker-compose.yml | 13 +++ img/docker.jpg | Bin 0 -> 188054 bytes img/test.jpg | Bin 0 -> 188054 bytes iris.script | 14 +++ module.xml | 27 +++-- src/cls/Ikon/Identicon.cls | 224 +++++++++++++++++++++++++++++++++++++ src/cls/Ikon/Processor.cls | 83 ++++++++++++++ 12 files changed, 503 insertions(+), 14 deletions(-) create mode 100644 Dockerfile create mode 100644 demo/demo.jpg create mode 100644 demo/dockerdemo.jpg create mode 100644 dev.md create mode 100644 docker-compose.yml create mode 100644 img/docker.jpg create mode 100644 img/test.jpg create mode 100644 iris.script create mode 100644 src/cls/Ikon/Identicon.cls create mode 100644 src/cls/Ikon/Processor.cls diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ed8eb37 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +# The most minimumalistic dockerfile possible. +# No embedded python support, no unit-testing, no aliases. +ARG IMAGE=intersystemsdc/iris-community +FROM $IMAGE + +WORKDIR /home/irisowner/dev +COPY .iris_init /home/irisowner/.iris_init + +RUN --mount=type=bind,src=.,dst=. \ + iris start IRIS && \ + iris session IRIS < iris.script && \ + iris stop IRIS quietly diff --git a/README.md b/README.md index 7c8707f..8731a1f 100644 --- a/README.md +++ b/README.md @@ -17,5 +17,32 @@ Result of example above: ![Result](https://github.com/AndreiLN/Ikon/blob/master/test.jpg) + +## DOCKER Support +### Prerequisites +Make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [Docker desktop](https://www.docker.com/products/docker-desktop) installed. +### Installation +Clone/git pull the repo into any local directory +``` +$ git clone https://github.com/AndreiLN/Ikon.git +``` +Open the terminal in this directory and run: +``` +$ docker-compose build +``` +Run IRIS container with your project: +``` +$ docker-compose up -d +``` +Test from docker console +``` +$ docker-compose exec iris1 iris session iris +USER> +``` +or using **WebTerminal** +``` +http://localhost:42773/terminal/ +``` ## Documentation and Discussion See the [Article on InterSystems Developer Community](https://community.intersystems.com/post/identicon-generator-cach%C3%A9) + diff --git a/demo/demo.jpg b/demo/demo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..59db615959a4a32ee20e9cfeb448d90e6b30041c GIT binary patch literal 188054 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 literal 0 HcmV?d00001 diff --git a/demo/dockerdemo.jpg b/demo/dockerdemo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bbe4fbe6db95325130e138a683e0fd7894c5cae6 GIT binary patch literal 188054 zcmeIz!3`e87DVBJCZ7G4gFSXqjpZB~kC6M=}w!7c+p7*5$^1jq|_j}&+zLY@Tm)h=r&wJjN63F{f z+uiSZ&-+pWd0%R~`#tY@UrHeFOKo?*=RNOB3FLjL?e6!y=Y1)Gyf3xg{hs%{FC~!o zrMA1@^Pcym1oFPrcK3VU^S+co-j~|$e$RW}mlDYPQrq3{dC&V&0(oC*yZb%wd0$E( z?@MiWzvn&gO9|wCsqOCfyytx>fxIuZ-Tj{Tye}n?_ocSG-}9dLr3CW6)OPoK-t)ec zK;DH8?|IMrQUZBjYP+8(*Y51*O$ye}n?_ocQE7vIREyytx>fxIuZJ#vX3 zJ~QumUrHeFOKl%6zL7_H&-+pWd0%RK+CE%-BaiZ)_oW2#zSQ=} zC4TtKyytx>fxIuZeYp5W9_2mnO9|wCsqK+V{P3B1&-+pWd0%S#aPf^i%6s0I63F{f z+as6w;WP7|_oW2#zSQ>N;v0FC_q;D9koTpwM=tThXXZWcO9|wCsqMqXH}WX&d0$E( z?@MiuT;hk%%zNIK63F{f+lPy9kq|=N%`&kBh9Bugg1bn};e-a)#QZoB&^! z_q^i-_;KL?<;lF`w&iB{I?hm=GT| zTsS~^GVi!;xf#BWGt?&e%gd8_&pS?l9~W6MUzc~>HV;*v$Z62yT$r);sasqr^-t&$V;Kzjnlqd6!+m@T* z>o`MglE1t>nfJWo1o&~074vm@$8Gaa++s=oB%&A9H2azcigtz3}43? zYLoos<;lF~9Vft#i>#Qh%R6qHhbm8UhT5c@0AH8)yyFD;ap3^v$-LvXf?Zd-1Kuj350N&fQkWZv_R6X3^1 zR?OGs9k;hmnZX{cbot}F0x|2 zF7LQ)9;!Ua8ETVq0(@QG^NthX$AtrwC-aWmmYd=0I74lczq~w|_q^i-_;HaH^L2U0 zZSzp&NzPE4loR0V@}75`06#7qpgfs(+_u~dU&k40llGT|Tx7+3UEXoqJXCp- zGt?&K1o*nV=N%`&j|&GVPv#xBEjPp0afaF?e|dQ_?|H`w@Z%yY=Iio~+vcIllboS8 zDJQ_!0e)OKKzTCnxNW%^zK%20Ci%1#|iM`!U4*YdB<(b&G2=cp*G21UY^W*-f;r_xX6n6y1e7Id8qOvXQ)le3Gj7! z&pS?l9~TZ#p3FOLTW*H0;|#S){_^r<-t&$V;KxN)%-7`|x6MP9CpklHQci%c%X{8& z0{pmefbwMCaoch;d>v<~P4btQC-a_noB%&AvSPk2@3?IqsyxXVYLjvTd|lr2juYU= zg#(l)^N!n=o8jv?Lv513ygZrryyFD;agi1Cb90@>QRocYM3aiut;) zDtvr6?|H`wTyR$Mj@#xJt~_}GL+umto_Cyprt-Z-dB<(bw>Dq*o{sx|Iq!ML30%NG z@3?J#;mVU2Fw{OF?|H`wXe!@Zly}^=d~5S{@9DVjm-C)?oWKSA^N!o*7p^>c0YmK* z@}75`fTr@jMR~_<%eOXP_nwaXemU=X#|d1(KkvA0e&NcK7ckU5A@6y|31}+cTazb?@o8@0atQcbvcl{PT|6<`=F!c>zQ16Y`#SoPehCy+wJ)ZOgYdU-zDl`+hm^ zdB+J{z(4P}ZGPd(lNT`5J|XXU#|daE-&>S-+_rpc^L6j(xbK(qo_CzU1^n}l+vXRp zJb3{_?Gy5zcbtHx^1VfQ$8F2EHedIij{AN&?|H`wT);o?xNUyn%99r`)IK5adB+K8 zD&Jd_cigsoYx8yQ>A3Hg^PYE{zyDq* zo{sx|Iq!ML30%NG@3?J#;mVU2Fw{OF?|H`wXe!@Zly}^=d~5S{@9DVjm-C)?oWKSA z^N!o*7p^>c0YmK*@}75`fTr@jMR~_<%eOXP_nwaXemU=X#|d1(KkvA0e&NcK7ckU5 QA@6y|31}+cTl75t04nfMkpKVy literal 0 HcmV?d00001 diff --git a/dev.md b/dev.md new file mode 100644 index 0000000..c2c8a64 --- /dev/null +++ b/dev.md @@ -0,0 +1,117 @@ +# useful commands +## clean up docker +use it when docker says "There is no space left on device". It will remove built but not used images and other temporary files. +``` +docker system prune -f +``` + +``` +docker rm -f $(docker ps -qa) +``` + +## build container with no cache +``` +docker-compose build --no-cache --progress=plain +``` +## start iris container +``` +docker-compose up -d +``` + +## open iris terminal in docker +``` +docker exec iris iris session iris -U IRISAPP +``` + + +## import objectscirpt code + +do $System.OBJ.LoadDir("/home/irisowner/dev/src","ck",,1) +## map iris key from Mac home directory to IRIS in container +- ~/iris.key:/usr/irissys/mgr/iris.key + +## install git in the docker image +## add git in dockerfile +USER root +RUN apt update && apt-get -y install git + +USER ${ISC_PACKAGE_MGRUSER} + + +## install docker-compose +``` +sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + +sudo chmod +x /usr/local/bin/docker-compose + +``` + +## load and test module +``` + +zpm "load /home/irisowner/dev" + +zpm "test dc-sample" +``` + +## select zpm test registry +``` +repo -n registry -r -url https://test.pm.community.intersystems.com/registry/ -user test -pass PassWord42 +``` + +## get back to public zpm registry +``` +repo -r -n registry -url https://pm.community.intersystems.com/ -user "" -pass "" +``` + +## export a global in runtime into the repo +``` +d $System.OBJ.Export("GlobalD.GBL","/irisrun/repo/src/gbl/GlobalD.xml") +``` + +## create a web app in dockerfile +``` +zn "%SYS" \ + write "Create web application ...",! \ + set webName = "/csp/irisweb" \ + set webProperties("NameSpace") = "IRISAPP" \ + set webProperties("Enabled") = 1 \ + set webProperties("CSPZENEnabled") = 1 \ + set webProperties("AutheEnabled") = 32 \ + set webProperties("iKnowEnabled") = 1 \ + set webProperties("DeepSeeEnabled") = 1 \ + set sc = ##class(Security.Applications).Create(webName, .webProperties) \ + write "Web application "_webName_" has been created!",! +``` + + + +``` +do $SYSTEM.OBJ.ImportDir("/opt/irisbuild/src",, "ck") +``` + + +### run tests described in the module + +IRISAPP>zpm +IRISAPP:zpm>load /irisrun/repo +IRISAPP:zpm>test package-name + +### install ZPM with one line + // Install ZPM + set $namespace="%SYS", name="DefaultSSL" do:'##class(Security.SSLConfigs).Exists(name) ##class(Security.SSLConfigs).Create(name) set url="https://pm.community.intersystems.com/packages/zpm/latest/installer" Do ##class(%Net.URLParser).Parse(url,.comp) set ht = ##class(%Net.HttpRequest).%New(), ht.Server = comp("host"), ht.Port = 443, ht.Https=1, ht.SSLConfiguration=name, st=ht.Get(comp("path")) quit:'st $System.Status.GetErrorText(st) set xml=##class(%File).TempFilename("xml"), tFile = ##class(%Stream.FileBinary).%New(), tFile.Filename = xml do tFile.CopyFromAndSave(ht.HttpResponse.Data) do ht.%Close(), $system.OBJ.Load(xml,"ck") do ##class(%File).Delete(xml) + + + + +docker run --rm --name iris-sql -d -p 9091:1972 -p 9092:52773  -e IRIS_PASSWORD=demo -e IRIS_USERNAME=demo intersystemsdc/iris-community + + +docker run --rm --name iris-ce -d -p 9091:1972 -p 9092:52773 -e IRIS_PASSWORD=demo -e IRIS_USERNAME=demo intersystemsdc/iris-community -a "echo 'zpm \"install webterminal\"' | iriscli" + + + +docker run --rm --name iris-sql -d -p 9092:52773 containers.intersystems.com/intersystems/iris-community:2023.1.0.229.0 + + +docker run --rm --name iris-ce -d -p 9092:52773 containers.intersystems.com/intersystems/iris-community:2023.1.0.229.0 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..070f5d6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3.6' +services: + iris: + build: + context: . + dockerfile: Dockerfile + restart: always + command: --check-caps false --ISCAgent false + ports: + - 41773:1972 + - 42773:52773 + volumes: + - ./:/home/irisowner/dev diff --git a/img/docker.jpg b/img/docker.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e83ea7ef5f0df0346fc5ae06ae5e7a135cf5e2d9 GIT binary patch literal 188054 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 literal 0 HcmV?d00001 diff --git a/img/test.jpg b/img/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3aa3e352366a865a60a540aa98509787aab755fe GIT binary patch literal 188054 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 P+r963&-+acyk7qRZyX*7 literal 0 HcmV?d00001 diff --git a/iris.script b/iris.script new file mode 100644 index 0000000..a50b716 --- /dev/null +++ b/iris.script @@ -0,0 +1,14 @@ + zn "%SYS" + + // Unexpire passwords and set up passwordless mode to simplify dev use. + // ** Comment out these two line for Production use ** + do ##class(Security.Users).UnExpireUserPasswords("*") + zpm "install passwordless" + + zn "USER" + + // Create /_vscode web app to support intersystems-community.testingmanager VS Code extension + zpm "install vscode-per-namespace-settings" + + zpm "load /home/irisowner/dev/ -v":1:1 + halt diff --git a/module.xml b/module.xml index 0c8232f..73872d5 100644 --- a/module.xml +++ b/module.xml @@ -1,14 +1,13 @@ - - - - - Ikon - 1.0.1 - Identicon generator for Intersystems Caché. Good to use in Mojo applications. - module - src - - - - - + + + + + Ikon + 1.0.2 + Identicon generator for Intersystems Caché. Good to use in Mojo applications. + module + src + + + + diff --git a/src/cls/Ikon/Identicon.cls b/src/cls/Ikon/Identicon.cls new file mode 100644 index 0000000..b95a350 --- /dev/null +++ b/src/cls/Ikon/Identicon.cls @@ -0,0 +1,224 @@ +/// Identicon Generator in COS
+/// Author: Andrei Luiz Nenevê - alneneve@gmail.com
+/// Requires: Caché 2016.2 or Newer

+/// Example:
+/// +/// ; Parameters=> Word, Directory, Size, Background amount of red, green, blue +/// Do ##class(Ikon.Identicon).%New("test","C:\Identicons\",250,255,255,155) +/// +Class Ikon.Identicon Extends %RegisteredObject +{ + +Property Name As %String; + +Property Hash As %DynamicArray; + +Property Color As %DynamicArray; + +Property Grid As %DynamicArray; + +Property GridPoint As %DynamicArray; + +Property PixelMap As %DynamicArray; + +Property Directory As %String [ InitialExpression = "C:\Identicons\" ]; + +Property FileFullName As %String; + +Property Size As %Integer [ InitialExpression = 250 ]; + +Property BackgroundColor As %String [ InitialExpression = "255,255,255" ]; + +Method HashInput() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set identicon = ##class(%SYSTEM.Encryption).MD5Hash(..Name) + Set ..Hash = ##class(%DynamicArray).%New() + For i=1:1:$Length(identicon){ + $$$THROWONERROR(tSC, ..Hash.%Push($ASCII($Extract(identicon,i)))) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method PickColor() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..Color = ##class(%DynamicArray).%New() + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(0))) //Red + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(1))) //Green + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(2))) //Blue + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method BuildGrid() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..Grid = ##class(%DynamicArray).%New() + For i=0:3:..Hash.%Size(){ + Quit:(i+3>(..Hash.%Size()-1)) + Set chunk = ##class(%DynamicArray).%New() + Set fst = ..Hash.%Get(i), sec = ..Hash.%Get(i+1) + $$$THROWONERROR(tSC, ..Grid.%Push(fst)) + $$$THROWONERROR(tSC, ..Grid.%Push(sec)) + $$$THROWONERROR(tSC, ..Grid.%Push(..Hash.%Get(i+2))) + $$$THROWONERROR(tSC, ..Grid.%Push(sec)) + $$$THROWONERROR(tSC, ..Grid.%Push(fst)) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method FilterOddSquares() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..GridPoint = ##class(%DynamicArray).%New() + Set iter = ..Grid.%GetIterator() + While iter.%GetNext(.key,.value){ + If value # 2 = 0{ + Set obj = ##class(%DynamicObject).%New() + Set obj.key = key + Set obj.value = value + $$$THROWONERROR(tSC, ..GridPoint.%Push(obj)) + } + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method BuildPixelMap() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..PixelMap = ##class(%DynamicArray).%New() + Set iter = ..GridPoint.%GetIterator() + While iter.%GetNext(.key,.value){ + Set horizontal = (value.key # 5) * (..Size/5) + Set vertical = (value.key \ 5) * (..Size/5) + + Set point = ##class(%DynamicObject).%New() + + Set cord = ##class(%DynamicObject).%New() + $$$THROWONERROR(tSC, cord.%Set("x",horizontal)) + $$$THROWONERROR(tSC, cord.%Set("y",vertical)) + $$$THROWONERROR(tSC, point.%Set("topLeft",cord)) + + Set cord = ##class(%DynamicObject).%New() + $$$THROWONERROR(tSC, cord.%Set("x",horizontal+(..Size/5))) + $$$THROWONERROR(tSC, cord.%Set("y",vertical+(..Size/5))) + $$$THROWONERROR(tSC, point.%Set("bottomRight",cord)) + + $$$THROWONERROR(tSC, ..PixelMap.%Push(point)) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method GenerateFileName() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + If '##class(%File).DirectoryExists(..Directory) { + Set tSC = ##class(%File).CreateDirectoryChain(..Directory) + } + Set ..FileFullName = ..Directory_..Name_".jpg" + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method CreateImage() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set tBack = $ListFromString(..BackgroundColor,",") + Set tImage = ##class(Ikon.Processor).New(..Size,..Size,$List(tBack,1),$List(tBack,2),$List(tBack,3)) + Do tImage.SetPen(..Color.%Get(0),..Color.%Get(1),..Color.%Get(2)) + Set iter = ..PixelMap.%GetIterator() + While iter.%GetNext(.key,.value){ + Set posInicialX = value.topLeft.x + Set posInicialY = value.topLeft.y + Set posFinalX = value.bottomRight.x + Set posFinalY = value.bottomRight.y + For y=posInicialY:1:posFinalY{ + For x=posInicialX:1:posFinalX{ + Do tImage.Plot(x,y) + } + } + } + s a=..FileFullName + o a:"WNS":10 e + u a + d tImage.WriteBitmap() + c a + d tImage.%Close() + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method Generate(pName As %String = "Caché", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status +{ + Set tSC = $$$OK + Try { + Set:pName'="" ..Name = pName + Set:pDirectory'="" ..Directory = pDirectory + Set ..BackgroundColor = Red_","_Green_","_Blue + Set ..Size = pSize + $$$THROWONERROR(tSC, ..HashInput()) + $$$THROWONERROR(tSC, ..PickColor()) + $$$THROWONERROR(tSC, ..BuildGrid()) + $$$THROWONERROR(tSC, ..FilterOddSquares()) + $$$THROWONERROR(tSC, ..BuildPixelMap()) + $$$THROWONERROR(tSC, ..GenerateFileName()) + $$$THROWONERROR(tSC, ..CreateImage()) + Write !,"File '"_..Directory_..Name_"' successfully generated!",! + } Catch tException { + Set:$$$ISERR(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method %OnNew(pName As %String = "", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status [ Private, ServerOnly = 1 ] +{ + Set tSC = $$$OK + Try { + Set:pName'="" ..Name = pName + Set:pDirectory'="" ..Directory = pDirectory + Set ..BackgroundColor = Red_","_Green_","_Blue + Set ..Size = pSize + If pName'=""{ + $$$THROWONERROR(tSC, ..HashInput()) + $$$THROWONERROR(tSC, ..PickColor()) + $$$THROWONERROR(tSC, ..BuildGrid()) + $$$THROWONERROR(tSC, ..FilterOddSquares()) + $$$THROWONERROR(tSC, ..BuildPixelMap()) + $$$THROWONERROR(tSC, ..GenerateFileName()) + $$$THROWONERROR(tSC, ..CreateImage()) + Write !,"File '"_..Directory_..Name_"' successfully generated!",! + } + } Catch tException { + Set:$$$ISERR(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +} + diff --git a/src/cls/Ikon/Processor.cls b/src/cls/Ikon/Processor.cls new file mode 100644 index 0000000..ec3b1c5 --- /dev/null +++ b/src/cls/Ikon/Processor.cls @@ -0,0 +1,83 @@ +/// This class is a refactored version from Captcha generator originally made by Fabio Gonçalves +///
This refactored version to do the generation of identicons was made by Andrei Luiz Nenevê +Class Ikon.Processor Extends %RegisteredObject [ ClassType = "", Not ProcedureBlock ] +{ + +Property Data [ MultiDimensional ]; + +Property Width As %Integer; + +Property Height As %Integer; + +Property PenColor As %String(TRUNCATE = 1); + +ClassMethod New(width As %Integer, height As %Integer, red As %Integer = 255, green As %Integer = 255, blue As %Integer = 255) As Ikon.Processor +{ + Set img = ##class(Ikon.Processor).%New() + Set img.Width = width,img.Height = height + For x = 1:1:width{ + For y = 1:1:height{ + Set img.Data(x,y) = $Char(blue,green,red) + } + } + Do img.SetPen(0,0,0) + Quit img +} + +Method SetPen(red As %Integer, green As %Integer, blue As %Integer) As %Status +{ + Set ..PenColor = $Char(blue,green,red) + Quit $$$OK +} + +Method Plot(x As %Integer, y As %Integer) As %Status +{ + Quit:(x<1||y<1||y>..Height||x>..Width) 1 + Set ..Data(x,y) = ..PenColor + Quit $$$OK +} + +ClassMethod SetBytes(decimal As %Integer, length As %Integer) As %String +{ + Set ret = "" + For i = 1:1:length{ + Set ret = ret_$Char(decimal#256), decimal = decimal/256 + } + Quit ret +} + +Method WriteBitmap() +{ + Set bfType = "BM", + bfSize = 0, + bfReserved1 = ..SetBytes(0,2), + bfReserved2=..SetBytes(0,2), + bfOffsetBits=..SetBytes(54,4), + biSize=..SetBytes(40,4), + biWidth=..SetBytes(..Width,4), + biHeight=..SetBytes(..Height,4), + biPlanes=..SetBytes(1,2), + biBitCount=..SetBytes(24,2), + biCompression=..SetBytes(0,4), + biSizeImage=..SetBytes(0,4), + biXPelsPerMeter=..SetBytes(0,4), + biYPelsPerMeter=..SetBytes(0,4), + biColorsUsed=..SetBytes(0,4), + biColorsImportant=..SetBytes(0,4), + padding=(..Width*3)#4, + padding=$s(padding=0:"",1:$e($c(0,0,0),1,4-padding)), + sizeimage=((..Width*3)+$l(padding))*..Height, + bfSize=..SetBytes(14+40+sizeimage,4), + biSizeImage=..SetBytes(sizeimage,4) + Write bfType_bfSize_bfReserved1_bfReserved2_bfOffsetBits + Write biSize_biWidth_biHeight_biPlanes_biBitCount_biCompression_biSizeImage_biXPelsPerMeter_biYPelsPerMeter_biColorsUsed_biColorsImportant + For y = ..Height:-1:1 { + For x=1:1:..Width { + Write ..Data(x,y) + } + Write padding + } +} + +} + From 471dffa078433a31f8e488a13073b190f9c3157f Mon Sep 17 00:00:00 2001 From: r-cemper Date: Fri, 23 Feb 2024 11:20:15 +0100 Subject: [PATCH 2/5] add docker + demo --- .devcontainer/devcontainer.json | 51 +++ .dockerignore | 3 + .gitattributes | 11 + .github/workflows/build-push-gcr.yaml | 19 + .github/workflows/bump-module-version.yml | 28 ++ .github/workflows/github-registry.yml | 25 ++ .github/workflows/objectscript-quality.yml | 12 + .github/workflows/runtests.yml | 28 ++ .gitignore | 5 + .iris_init | 7 + .vscode/extensions.json | 17 + .vscode/launch.json | 18 + .vscode/settings.json | 22 + src/cls/Ikon/Identicon.cls | 448 ++++++++++----------- src/cls/Ikon/Processor.cls | 166 ++++---- 15 files changed, 553 insertions(+), 307 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/workflows/build-push-gcr.yaml create mode 100644 .github/workflows/bump-module-version.yml create mode 100644 .github/workflows/github-registry.yml create mode 100644 .github/workflows/objectscript-quality.yml create mode 100644 .github/workflows/runtests.yml create mode 100644 .gitignore create mode 100644 .iris_init create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..5b76b8e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,51 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.224.2/containers/docker-existing-docker-compose +{ + "name": "intersystems-iris-dev-template devcontainer", + + // Use the same recipe as creates the container we use when working locally. + "dockerComposeFile": [ + "../docker-compose.yml" + ], + + "service": "iris", + + "workspaceFolder": "/home/irisowner/dev", + + // This provides the elements of the connection object which require different values when connecting to the workspace within the container, + // versus those in .vscode/settings.json which apply when operating locally on the workspace files. + // We define and use a `server` so that (a) a user-level `objectscript.conn.server` properly doesn't override us, and (b) so InterSystems + // Server Manager can also be used. + "settings": { + "objectscript.conn" :{ + "server": "devcontainer", + "active": true, + }, + "intersystems.servers": { + "devcontainer": { + "username": "SuperUser", + "password": "SYS", + "webServer": { + "scheme": "http", + "host": "127.0.0.1", + "port": 52773 + }, + }, + }, + "python.defaultInterpreterPath":"/usr/irissys/bin/irispython" + }, + + // Add the IDs of extensions we want installed when the container is created. + // Currently (March 2022) `intersystems.language-server` fails to run within the container (alpine platform). + // Issue is probably https://github.com/intersystems/language-server/issues/185 and/or https://github.com/intersystems/language-server/issues/32 + // Crash gets reported to the user, after which `intersystems-community.vscode-objectscript` falls back to + // using its TextMate grammar for code coloring. + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "intersystems-community.vscode-objectscript", + "intersystems.language-server", + "intersystems-community.servermanager", + "ms-vscode.docker" + ], +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..24c989d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +**/.DS_Store +iris-main.log +.git \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4a94c94 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +*.cls linguist-language=ObjectScript +*.mac linguist-language=ObjectScript +*.int linguist-language=ObjectScript +*.inc linguist-language=ObjectScript +*.csp linguist-language=Html + +*.sh text eol=lf +*.cls text eol=lf +*.mac text eol=lf +*.int text eol=lf +Dockerfil* text eol=lf diff --git a/.github/workflows/build-push-gcr.yaml b/.github/workflows/build-push-gcr.yaml new file mode 100644 index 0000000..aa786f9 --- /dev/null +++ b/.github/workflows/build-push-gcr.yaml @@ -0,0 +1,19 @@ +name: Cloud Run Deploy + +on: + push: + branches: + - master + - main + workflow_dispatch: + +jobs: + deploy: + uses: intersystems-community/demo-deployment/.github/workflows/deployment.yml@master + with: + # Replace the name: parameter below to have your application deployed at + # https://project-name.demo.community.intersystems.com/ + name: project-name + secrets: + # Do not forget to add Secret in GitHub Repoository Settings with name SERVICE_ACCOUNT_KEY + SERVICE_ACCOUNT_KEY: ${{ secrets.SERVICE_ACCOUNT_KEY }} \ No newline at end of file diff --git a/.github/workflows/bump-module-version.yml b/.github/workflows/bump-module-version.yml new file mode 100644 index 0000000..28689cf --- /dev/null +++ b/.github/workflows/bump-module-version.yml @@ -0,0 +1,28 @@ +name: versionbump + +on: + push: + branches: + - master + - main + release: + types: + - released +permissions: + contents: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Bump version + run: | + git config --global user.name 'ProjectBot' + git config --global user.email 'bot@users.noreply.github.com' + VERSION=$(sed -n '0,/.*\(.*\)<\/Version>.*/s//\1/p' module.xml) + VERSION=`echo $VERSION | awk -F. '/[0-9]+\./{$NF++;print}' OFS=.` + sed -i "0,/\(.*\)<\/Version>/s//$VERSION<\/Version>/" module.xml + git add module.xml + git commit -m 'auto bump version' + git push diff --git a/.github/workflows/github-registry.yml b/.github/workflows/github-registry.yml new file mode 100644 index 0000000..d2e1234 --- /dev/null +++ b/.github/workflows/github-registry.yml @@ -0,0 +1,25 @@ +name: Build and publish a Docker image to ghcr.io +on: + + # publish on pushes to the main branch (image tagged as "latest") + # image name: will be: ghcr.io/${{ github.repository }}:latest + # e.g.: ghcr.io/intersystems-community/intersystems-iris-dev-template:latest + push: + branches: + - master + +jobs: + docker_publish: + runs-on: "ubuntu-20.04" + + steps: + - uses: actions/checkout@v2 + + # https://github.com/marketplace/actions/push-to-ghcr + - name: Build and publish a Docker image for ${{ github.repository }} + uses: macbre/push-to-ghcr@master + with: + image_name: ${{ github.repository }} + github_token: ${{ secrets.GITHUB_TOKEN }} + # optionally push to the Docker Hub (docker.io) + # docker_io_token: ${{ secrets.DOCKER_IO_ACCESS_TOKEN }} # see https://hub.docker.com/settings/security \ No newline at end of file diff --git a/.github/workflows/objectscript-quality.yml b/.github/workflows/objectscript-quality.yml new file mode 100644 index 0000000..4bda31c --- /dev/null +++ b/.github/workflows/objectscript-quality.yml @@ -0,0 +1,12 @@ +name: objectscriptquality +on: push + +jobs: + linux: + name: Linux build + runs-on: ubuntu-latest + + steps: + - name: Execute ObjectScript Quality Analysis + run: wget https://raw.githubusercontent.com/litesolutions/objectscriptquality-jenkins-integration/master/iris-community-hook.sh && sh ./iris-community-hook.sh + diff --git a/.github/workflows/runtests.yml b/.github/workflows/runtests.yml new file mode 100644 index 0000000..7464209 --- /dev/null +++ b/.github/workflows/runtests.yml @@ -0,0 +1,28 @@ +name: unittest + +on: + push: + branches: + - master + - main + pull_request: + branches: + - master + - main + release: + types: + - released + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build and Test + uses: docker/build-push-action@v2 + with: + context: . + push: false + load: true + tags: ${{ github.repository }}:${{ github.sha }} + build-args: TESTS=1 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..725c144 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +iris-main.log +.env +.git + diff --git a/.iris_init b/.iris_init new file mode 100644 index 0000000..5d29201 --- /dev/null +++ b/.iris_init @@ -0,0 +1,7 @@ +:alias enablebi do EnableDeepSee^%SYS.cspServer("/csp/"_$zcvt($namespace,"L")) ; +:alias ssl x "n $namespace set $namespace=""%SYS"", name=$S(""$1""="""":""DefaultSSL"",1:""$1"") do:'##class(Security.SSLConfigs).Exists(name) ##class(Security.SSLConfigs).Create(name)" ; +:alias createdb do $SYSTEM.SQL.Execute("CREATE DATABASE $1") ; +:alias installipm s r=##class(%Net.HttpRequest).%New(),r.Server="pm.community.intersystems.com",r.SSLConfiguration="ISC.FeatureTracker.SSL.Config" d r.Get("/packages/zpm/latest/installer"),$system.OBJ.LoadStream(r.HttpResponse.Data,"c") ; +:alias add%all x "n $namespace set $namespace=""%SYS"",P(""Globals"")=""%DEFAULTDB"",sc=##class(Config.Namespaces).Create(""%All"",.P)" ; +:alias exportglobal d $System.OBJ.Export("$1.GBL","$2$1.xml") ; +:alias rcc Write !,"Hi "_$namespace,! ; \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..0638285 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,17 @@ +{ + "recommendations": [ + "eamodio.gitlens", + "georgejames.gjlocate", + "github.copilot", + "intersystems-community.servermanager", + "intersystems-community.sqltools-intersystems-driver", + "intersystems-community.testingmanager", + "intersystems-community.vscode-objectscript", + "intersystems.language-server", + "mohsen1.prettify-json", + "ms-azuretools.vscode-docker", + "ms-python.python", + "ms-python.vscode-pylance", + "ms-vscode-remote.remote-containers" + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7da4968 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "objectscript", + "request": "launch", + "name": "ObjectScript Debug Class", + "program": "##class(dc.sample.ObjectScript).Test()", + }, + { + "type": "objectscript", + "request": "attach", + "name": "ObjectScript Attach", + "processId": "${command:PickProcess}", + "system": true + } + ] + } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ca5d71a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "files.associations": { + + "Dockerfile*": "dockerfile", + "iris.script": "objectscript" + }, + "objectscript.conn" :{ + "active": true, + "ns": "IRISAPP", + "username": "_SYSTEM", + "password": "SYS", + "docker-compose": { + "service": "iris", + "internalPort": 52773 + }, + "links": { + "UnitTest Portal": "${serverUrl}/csp/sys/%25UnitTest.Portal.Home.cls?$NAMESPACE=IRISAPP" + } + }, + "intersystems.testingManager.client.relativeTestRoot": "tests" + +} \ No newline at end of file diff --git a/src/cls/Ikon/Identicon.cls b/src/cls/Ikon/Identicon.cls index b95a350..0afd645 100644 --- a/src/cls/Ikon/Identicon.cls +++ b/src/cls/Ikon/Identicon.cls @@ -1,224 +1,224 @@ -/// Identicon Generator in COS
-/// Author: Andrei Luiz Nenevê - alneneve@gmail.com
-/// Requires: Caché 2016.2 or Newer

-/// Example:
-/// -/// ; Parameters=> Word, Directory, Size, Background amount of red, green, blue -/// Do ##class(Ikon.Identicon).%New("test","C:\Identicons\",250,255,255,155) -/// -Class Ikon.Identicon Extends %RegisteredObject -{ - -Property Name As %String; - -Property Hash As %DynamicArray; - -Property Color As %DynamicArray; - -Property Grid As %DynamicArray; - -Property GridPoint As %DynamicArray; - -Property PixelMap As %DynamicArray; - -Property Directory As %String [ InitialExpression = "C:\Identicons\" ]; - -Property FileFullName As %String; - -Property Size As %Integer [ InitialExpression = 250 ]; - -Property BackgroundColor As %String [ InitialExpression = "255,255,255" ]; - -Method HashInput() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set identicon = ##class(%SYSTEM.Encryption).MD5Hash(..Name) - Set ..Hash = ##class(%DynamicArray).%New() - For i=1:1:$Length(identicon){ - $$$THROWONERROR(tSC, ..Hash.%Push($ASCII($Extract(identicon,i)))) - } - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method PickColor() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set ..Color = ##class(%DynamicArray).%New() - $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(0))) //Red - $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(1))) //Green - $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(2))) //Blue - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method BuildGrid() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set ..Grid = ##class(%DynamicArray).%New() - For i=0:3:..Hash.%Size(){ - Quit:(i+3>(..Hash.%Size()-1)) - Set chunk = ##class(%DynamicArray).%New() - Set fst = ..Hash.%Get(i), sec = ..Hash.%Get(i+1) - $$$THROWONERROR(tSC, ..Grid.%Push(fst)) - $$$THROWONERROR(tSC, ..Grid.%Push(sec)) - $$$THROWONERROR(tSC, ..Grid.%Push(..Hash.%Get(i+2))) - $$$THROWONERROR(tSC, ..Grid.%Push(sec)) - $$$THROWONERROR(tSC, ..Grid.%Push(fst)) - } - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method FilterOddSquares() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set ..GridPoint = ##class(%DynamicArray).%New() - Set iter = ..Grid.%GetIterator() - While iter.%GetNext(.key,.value){ - If value # 2 = 0{ - Set obj = ##class(%DynamicObject).%New() - Set obj.key = key - Set obj.value = value - $$$THROWONERROR(tSC, ..GridPoint.%Push(obj)) - } - } - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method BuildPixelMap() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set ..PixelMap = ##class(%DynamicArray).%New() - Set iter = ..GridPoint.%GetIterator() - While iter.%GetNext(.key,.value){ - Set horizontal = (value.key # 5) * (..Size/5) - Set vertical = (value.key \ 5) * (..Size/5) - - Set point = ##class(%DynamicObject).%New() - - Set cord = ##class(%DynamicObject).%New() - $$$THROWONERROR(tSC, cord.%Set("x",horizontal)) - $$$THROWONERROR(tSC, cord.%Set("y",vertical)) - $$$THROWONERROR(tSC, point.%Set("topLeft",cord)) - - Set cord = ##class(%DynamicObject).%New() - $$$THROWONERROR(tSC, cord.%Set("x",horizontal+(..Size/5))) - $$$THROWONERROR(tSC, cord.%Set("y",vertical+(..Size/5))) - $$$THROWONERROR(tSC, point.%Set("bottomRight",cord)) - - $$$THROWONERROR(tSC, ..PixelMap.%Push(point)) - } - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method GenerateFileName() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - If '##class(%File).DirectoryExists(..Directory) { - Set tSC = ##class(%File).CreateDirectoryChain(..Directory) - } - Set ..FileFullName = ..Directory_..Name_".jpg" - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method CreateImage() As %Status [ Private ] -{ - Set tSC = $$$OK - Try { - Set tBack = $ListFromString(..BackgroundColor,",") - Set tImage = ##class(Ikon.Processor).New(..Size,..Size,$List(tBack,1),$List(tBack,2),$List(tBack,3)) - Do tImage.SetPen(..Color.%Get(0),..Color.%Get(1),..Color.%Get(2)) - Set iter = ..PixelMap.%GetIterator() - While iter.%GetNext(.key,.value){ - Set posInicialX = value.topLeft.x - Set posInicialY = value.topLeft.y - Set posFinalX = value.bottomRight.x - Set posFinalY = value.bottomRight.y - For y=posInicialY:1:posFinalY{ - For x=posInicialX:1:posFinalX{ - Do tImage.Plot(x,y) - } - } - } - s a=..FileFullName - o a:"WNS":10 e - u a - d tImage.WriteBitmap() - c a - d tImage.%Close() - } Catch tException { - Set:$$$ISOK(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method Generate(pName As %String = "Caché", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status -{ - Set tSC = $$$OK - Try { - Set:pName'="" ..Name = pName - Set:pDirectory'="" ..Directory = pDirectory - Set ..BackgroundColor = Red_","_Green_","_Blue - Set ..Size = pSize - $$$THROWONERROR(tSC, ..HashInput()) - $$$THROWONERROR(tSC, ..PickColor()) - $$$THROWONERROR(tSC, ..BuildGrid()) - $$$THROWONERROR(tSC, ..FilterOddSquares()) - $$$THROWONERROR(tSC, ..BuildPixelMap()) - $$$THROWONERROR(tSC, ..GenerateFileName()) - $$$THROWONERROR(tSC, ..CreateImage()) - Write !,"File '"_..Directory_..Name_"' successfully generated!",! - } Catch tException { - Set:$$$ISERR(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -Method %OnNew(pName As %String = "", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status [ Private, ServerOnly = 1 ] -{ - Set tSC = $$$OK - Try { - Set:pName'="" ..Name = pName - Set:pDirectory'="" ..Directory = pDirectory - Set ..BackgroundColor = Red_","_Green_","_Blue - Set ..Size = pSize - If pName'=""{ - $$$THROWONERROR(tSC, ..HashInput()) - $$$THROWONERROR(tSC, ..PickColor()) - $$$THROWONERROR(tSC, ..BuildGrid()) - $$$THROWONERROR(tSC, ..FilterOddSquares()) - $$$THROWONERROR(tSC, ..BuildPixelMap()) - $$$THROWONERROR(tSC, ..GenerateFileName()) - $$$THROWONERROR(tSC, ..CreateImage()) - Write !,"File '"_..Directory_..Name_"' successfully generated!",! - } - } Catch tException { - Set:$$$ISERR(tSC) tSC = tException.AsStatus() - } - Quit tSC -} - -} - +/// Identicon Generator in COS
+/// Author: Andrei Luiz Nenevê - alneneve@gmail.com
+/// Requires: Caché 2016.2 or Newer

+/// Example:
+/// +/// ; Parameters=> Word, Directory, Size, Background amount of red, green, blue +/// Do ##class(Ikon.Identicon).%New("test","C:\Identicons\",250,255,255,155) +/// +Class Ikon.Identicon Extends %RegisteredObject +{ + +Property Name As %String; + +Property Hash As %DynamicArray; + +Property Color As %DynamicArray; + +Property Grid As %DynamicArray; + +Property GridPoint As %DynamicArray; + +Property PixelMap As %DynamicArray; + +Property Directory As %String [ InitialExpression = "C:\Identicons\" ]; + +Property FileFullName As %String; + +Property Size As %Integer [ InitialExpression = 250 ]; + +Property BackgroundColor As %String [ InitialExpression = "255,255,255" ]; + +Method HashInput() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set identicon = ##class(%SYSTEM.Encryption).MD5Hash(..Name) + Set ..Hash = ##class(%DynamicArray).%New() + For i=1:1:$Length(identicon){ + $$$THROWONERROR(tSC, ..Hash.%Push($ASCII($Extract(identicon,i)))) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method PickColor() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..Color = ##class(%DynamicArray).%New() + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(0))) //Red + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(1))) //Green + $$$THROWONERROR(tSC, ..Color.%Push(..Hash.%Get(2))) //Blue + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method BuildGrid() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..Grid = ##class(%DynamicArray).%New() + For i=0:3:..Hash.%Size(){ + Quit:(i+3>(..Hash.%Size()-1)) + Set chunk = ##class(%DynamicArray).%New() + Set fst = ..Hash.%Get(i), sec = ..Hash.%Get(i+1) + $$$THROWONERROR(tSC, ..Grid.%Push(fst)) + $$$THROWONERROR(tSC, ..Grid.%Push(sec)) + $$$THROWONERROR(tSC, ..Grid.%Push(..Hash.%Get(i+2))) + $$$THROWONERROR(tSC, ..Grid.%Push(sec)) + $$$THROWONERROR(tSC, ..Grid.%Push(fst)) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method FilterOddSquares() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..GridPoint = ##class(%DynamicArray).%New() + Set iter = ..Grid.%GetIterator() + While iter.%GetNext(.key,.value){ + If value # 2 = 0{ + Set obj = ##class(%DynamicObject).%New() + Set obj.key = key + Set obj.value = value + $$$THROWONERROR(tSC, ..GridPoint.%Push(obj)) + } + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method BuildPixelMap() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set ..PixelMap = ##class(%DynamicArray).%New() + Set iter = ..GridPoint.%GetIterator() + While iter.%GetNext(.key,.value){ + Set horizontal = (value.key # 5) * (..Size/5) + Set vertical = (value.key \ 5) * (..Size/5) + + Set point = ##class(%DynamicObject).%New() + + Set cord = ##class(%DynamicObject).%New() + $$$THROWONERROR(tSC, cord.%Set("x",horizontal)) + $$$THROWONERROR(tSC, cord.%Set("y",vertical)) + $$$THROWONERROR(tSC, point.%Set("topLeft",cord)) + + Set cord = ##class(%DynamicObject).%New() + $$$THROWONERROR(tSC, cord.%Set("x",horizontal+(..Size/5))) + $$$THROWONERROR(tSC, cord.%Set("y",vertical+(..Size/5))) + $$$THROWONERROR(tSC, point.%Set("bottomRight",cord)) + + $$$THROWONERROR(tSC, ..PixelMap.%Push(point)) + } + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method GenerateFileName() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + If '##class(%File).DirectoryExists(..Directory) { + Set tSC = ##class(%File).CreateDirectoryChain(..Directory) + } + Set ..FileFullName = ..Directory_..Name_".jpg" + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method CreateImage() As %Status [ Private ] +{ + Set tSC = $$$OK + Try { + Set tBack = $ListFromString(..BackgroundColor,",") + Set tImage = ##class(Ikon.Processor).New(..Size,..Size,$List(tBack,1),$List(tBack,2),$List(tBack,3)) + Do tImage.SetPen(..Color.%Get(0),..Color.%Get(1),..Color.%Get(2)) + Set iter = ..PixelMap.%GetIterator() + While iter.%GetNext(.key,.value){ + Set posInicialX = value.topLeft.x + Set posInicialY = value.topLeft.y + Set posFinalX = value.bottomRight.x + Set posFinalY = value.bottomRight.y + For y=posInicialY:1:posFinalY{ + For x=posInicialX:1:posFinalX{ + Do tImage.Plot(x,y) + } + } + } + s a=..FileFullName + o a:"WNS":10 e + u a + d tImage.WriteBitmap() + c a + d tImage.%Close() + } Catch tException { + Set:$$$ISOK(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method Generate(pName As %String = "Caché", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status +{ + Set tSC = $$$OK + Try { + Set:pName'="" ..Name = pName + Set:pDirectory'="" ..Directory = pDirectory + Set ..BackgroundColor = Red_","_Green_","_Blue + Set ..Size = pSize + $$$THROWONERROR(tSC, ..HashInput()) + $$$THROWONERROR(tSC, ..PickColor()) + $$$THROWONERROR(tSC, ..BuildGrid()) + $$$THROWONERROR(tSC, ..FilterOddSquares()) + $$$THROWONERROR(tSC, ..BuildPixelMap()) + $$$THROWONERROR(tSC, ..GenerateFileName()) + $$$THROWONERROR(tSC, ..CreateImage()) + Write !,"File '"_..Directory_..Name_"' successfully generated!",! + } Catch tException { + Set:$$$ISERR(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +Method %OnNew(pName As %String = "", pDirectory As %String = "", pSize = 250, Red As %Integer = 255, Green As %Integer = 255, Blue As %Integer = 255) As %Status [ Private, ServerOnly = 1 ] +{ + Set tSC = $$$OK + Try { + Set:pName'="" ..Name = pName + Set:pDirectory'="" ..Directory = pDirectory + Set ..BackgroundColor = Red_","_Green_","_Blue + Set ..Size = pSize + If pName'=""{ + $$$THROWONERROR(tSC, ..HashInput()) + $$$THROWONERROR(tSC, ..PickColor()) + $$$THROWONERROR(tSC, ..BuildGrid()) + $$$THROWONERROR(tSC, ..FilterOddSquares()) + $$$THROWONERROR(tSC, ..BuildPixelMap()) + $$$THROWONERROR(tSC, ..GenerateFileName()) + $$$THROWONERROR(tSC, ..CreateImage()) + Write !,"File '"_..Directory_..Name_"' successfully generated!",! + } + } Catch tException { + Set:$$$ISERR(tSC) tSC = tException.AsStatus() + } + Quit tSC +} + +} + diff --git a/src/cls/Ikon/Processor.cls b/src/cls/Ikon/Processor.cls index ec3b1c5..75f9692 100644 --- a/src/cls/Ikon/Processor.cls +++ b/src/cls/Ikon/Processor.cls @@ -1,83 +1,83 @@ -/// This class is a refactored version from Captcha generator originally made by Fabio Gonçalves -///
This refactored version to do the generation of identicons was made by Andrei Luiz Nenevê -Class Ikon.Processor Extends %RegisteredObject [ ClassType = "", Not ProcedureBlock ] -{ - -Property Data [ MultiDimensional ]; - -Property Width As %Integer; - -Property Height As %Integer; - -Property PenColor As %String(TRUNCATE = 1); - -ClassMethod New(width As %Integer, height As %Integer, red As %Integer = 255, green As %Integer = 255, blue As %Integer = 255) As Ikon.Processor -{ - Set img = ##class(Ikon.Processor).%New() - Set img.Width = width,img.Height = height - For x = 1:1:width{ - For y = 1:1:height{ - Set img.Data(x,y) = $Char(blue,green,red) - } - } - Do img.SetPen(0,0,0) - Quit img -} - -Method SetPen(red As %Integer, green As %Integer, blue As %Integer) As %Status -{ - Set ..PenColor = $Char(blue,green,red) - Quit $$$OK -} - -Method Plot(x As %Integer, y As %Integer) As %Status -{ - Quit:(x<1||y<1||y>..Height||x>..Width) 1 - Set ..Data(x,y) = ..PenColor - Quit $$$OK -} - -ClassMethod SetBytes(decimal As %Integer, length As %Integer) As %String -{ - Set ret = "" - For i = 1:1:length{ - Set ret = ret_$Char(decimal#256), decimal = decimal/256 - } - Quit ret -} - -Method WriteBitmap() -{ - Set bfType = "BM", - bfSize = 0, - bfReserved1 = ..SetBytes(0,2), - bfReserved2=..SetBytes(0,2), - bfOffsetBits=..SetBytes(54,4), - biSize=..SetBytes(40,4), - biWidth=..SetBytes(..Width,4), - biHeight=..SetBytes(..Height,4), - biPlanes=..SetBytes(1,2), - biBitCount=..SetBytes(24,2), - biCompression=..SetBytes(0,4), - biSizeImage=..SetBytes(0,4), - biXPelsPerMeter=..SetBytes(0,4), - biYPelsPerMeter=..SetBytes(0,4), - biColorsUsed=..SetBytes(0,4), - biColorsImportant=..SetBytes(0,4), - padding=(..Width*3)#4, - padding=$s(padding=0:"",1:$e($c(0,0,0),1,4-padding)), - sizeimage=((..Width*3)+$l(padding))*..Height, - bfSize=..SetBytes(14+40+sizeimage,4), - biSizeImage=..SetBytes(sizeimage,4) - Write bfType_bfSize_bfReserved1_bfReserved2_bfOffsetBits - Write biSize_biWidth_biHeight_biPlanes_biBitCount_biCompression_biSizeImage_biXPelsPerMeter_biYPelsPerMeter_biColorsUsed_biColorsImportant - For y = ..Height:-1:1 { - For x=1:1:..Width { - Write ..Data(x,y) - } - Write padding - } -} - -} - +/// This class is a refactored version from Captcha generator originally made by Fabio Gonçalves +///
This refactored version to do the generation of identicons was made by Andrei Luiz Nenevê +Class Ikon.Processor Extends %RegisteredObject [ ClassType = "", Not ProcedureBlock ] +{ + +Property Data [ MultiDimensional ]; + +Property Width As %Integer; + +Property Height As %Integer; + +Property PenColor As %String(TRUNCATE = 1); + +ClassMethod New(width As %Integer, height As %Integer, red As %Integer = 255, green As %Integer = 255, blue As %Integer = 255) As Ikon.Processor +{ + Set img = ##class(Ikon.Processor).%New() + Set img.Width = width,img.Height = height + For x = 1:1:width{ + For y = 1:1:height{ + Set img.Data(x,y) = $Char(blue,green,red) + } + } + Do img.SetPen(0,0,0) + Quit img +} + +Method SetPen(red As %Integer, green As %Integer, blue As %Integer) As %Status +{ + Set ..PenColor = $Char(blue,green,red) + Quit $$$OK +} + +Method Plot(x As %Integer, y As %Integer) As %Status +{ + Quit:(x<1||y<1||y>..Height||x>..Width) 1 + Set ..Data(x,y) = ..PenColor + Quit $$$OK +} + +ClassMethod SetBytes(decimal As %Integer, length As %Integer) As %String +{ + Set ret = "" + For i = 1:1:length{ + Set ret = ret_$Char(decimal#256), decimal = decimal/256 + } + Quit ret +} + +Method WriteBitmap() +{ + Set bfType = "BM", + bfSize = 0, + bfReserved1 = ..SetBytes(0,2), + bfReserved2=..SetBytes(0,2), + bfOffsetBits=..SetBytes(54,4), + biSize=..SetBytes(40,4), + biWidth=..SetBytes(..Width,4), + biHeight=..SetBytes(..Height,4), + biPlanes=..SetBytes(1,2), + biBitCount=..SetBytes(24,2), + biCompression=..SetBytes(0,4), + biSizeImage=..SetBytes(0,4), + biXPelsPerMeter=..SetBytes(0,4), + biYPelsPerMeter=..SetBytes(0,4), + biColorsUsed=..SetBytes(0,4), + biColorsImportant=..SetBytes(0,4), + padding=(..Width*3)#4, + padding=$s(padding=0:"",1:$e($c(0,0,0),1,4-padding)), + sizeimage=((..Width*3)+$l(padding))*..Height, + bfSize=..SetBytes(14+40+sizeimage,4), + biSizeImage=..SetBytes(sizeimage,4) + Write bfType_bfSize_bfReserved1_bfReserved2_bfOffsetBits + Write biSize_biWidth_biHeight_biPlanes_biBitCount_biCompression_biSizeImage_biXPelsPerMeter_biYPelsPerMeter_biColorsUsed_biColorsImportant + For y = ..Height:-1:1 { + For x=1:1:..Width { + Write ..Data(x,y) + } + Write padding + } +} + +} + From f627a92860a87dc07c8f997947245cf7a0b068b8 Mon Sep 17 00:00:00 2001 From: r-cemper <146277387+r-cemper@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:09:37 +0100 Subject: [PATCH 3/5] Update iris.script --- iris.script | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/iris.script b/iris.script index a50b716..9797337 100644 --- a/iris.script +++ b/iris.script @@ -1,14 +1,19 @@ zn "%SYS" - // Unexpire passwords and set up passwordless mode to simplify dev use. - // ** Comment out these two line for Production use ** do ##class(Security.Users).UnExpireUserPasswords("*") zpm "install passwordless" zn "USER" - // Create /_vscode web app to support intersystems-community.testingmanager VS Code extension zpm "install vscode-per-namespace-settings" + zpm "install webterminal" - zpm "load /home/irisowner/dev/ -v":1:1 + // this should be the place for individual application code. + + zn "USER" + zpm "install MDX2JSON" + zpm "install samples-bi" + do EnableDeepSee^%SYS.cspServer("/csp(user/") + zpm "list" + halt From 7a24fc0a4e143f2de1ec9101042fd2478082d72d Mon Sep 17 00:00:00 2001 From: r-cemper <146277387+r-cemper@users.noreply.github.com> Date: Sun, 25 Feb 2024 23:05:18 +0100 Subject: [PATCH 4/5] Update iris.script --- iris.script | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/iris.script b/iris.script index 9797337..a50b716 100644 --- a/iris.script +++ b/iris.script @@ -1,19 +1,14 @@ zn "%SYS" + // Unexpire passwords and set up passwordless mode to simplify dev use. + // ** Comment out these two line for Production use ** do ##class(Security.Users).UnExpireUserPasswords("*") zpm "install passwordless" zn "USER" + // Create /_vscode web app to support intersystems-community.testingmanager VS Code extension zpm "install vscode-per-namespace-settings" - zpm "install webterminal" - // this should be the place for individual application code. - - zn "USER" - zpm "install MDX2JSON" - zpm "install samples-bi" - do EnableDeepSee^%SYS.cspServer("/csp(user/") - zpm "list" - + zpm "load /home/irisowner/dev/ -v":1:1 halt From 252d57c786bc05e2e4d832b1b7c40e7efa64e483 Mon Sep 17 00:00:00 2001 From: r-cemper <146277387+r-cemper@users.noreply.github.com> Date: Tue, 9 Apr 2024 19:01:35 +0200 Subject: [PATCH 5/5] "ns": "USER" --- .vscode/settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ca5d71a..366f779 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ }, "objectscript.conn" :{ "active": true, - "ns": "IRISAPP", + "ns": "USER", "username": "_SYSTEM", "password": "SYS", "docker-compose": { @@ -19,4 +19,4 @@ }, "intersystems.testingManager.client.relativeTestRoot": "tests" -} \ No newline at end of file +}