1+ package  processing.app.api 
2+ 
3+ import  com.github.ajalt.clikt.command.SuspendingCliktCommand 
4+ import  com.github.ajalt.clikt.core.Context 
5+ import  com.github.ajalt.clikt.core.subcommands 
6+ import  kotlinx.serialization.encodeToString 
7+ import  kotlinx.serialization.json.Json 
8+ import  processing.app.Platform 
9+ import  processing.app.api.Sketch.Companion.getSketches 
10+ import  java.io.File 
11+ 
12+ class  Contributions : SuspendingCliktCommand (){
13+     override  fun  help (context :  Context ) =  " Manage Processing contributions" 
14+     override  suspend  fun  run () {
15+         System .setProperty(" java.awt.headless" " true" 
16+     }
17+     init  {
18+         subcommands(Examples ())
19+     }
20+ 
21+     class  Examples : SuspendingCliktCommand (" examples" 
22+         override  fun  help (context :  Context ) =  " Manage Processing examples" 
23+         override  suspend  fun  run () {
24+         }
25+         init  {
26+             subcommands(ExamplesList ())
27+         }
28+     }
29+ 
30+     class  ExamplesList : SuspendingCliktCommand (" list" 
31+ 
32+ 
33+         val  serializer =  Json  {
34+             prettyPrint =  true 
35+         }
36+ 
37+         override  fun  help (context :  Context ) =  " List all examples" 
38+         override  suspend  fun  run () {
39+             Platform .init ()
40+             //  TODO: Decouple modes listing from `Base` class, defaulting to Java mode for now
41+             //  TODO: Allow the user to change the sketchbook location
42+             //  TODO: Currently blocked since `Base.getSketchbookFolder()` is not available in headless mode
43+             val  sketchbookFolder =  Platform .getDefaultSketchbookFolder()
44+             val  resourcesDir =  System .getProperty(" compose.application.resources.dir" 
45+ 
46+             val  javaMode =  " $resourcesDir /modes/java" 
47+ 
48+             val  javaModeExamples =  File (" $javaMode /examples" 
49+                 .listFiles()
50+                 ?.map { getSketches(it)}
51+                 ? :  emptyList()
52+ 
53+             val  javaModeLibrariesExamples =  File (" $javaMode /libraries" 
54+                 .listFiles{ it.isDirectory }
55+                 ?.map { library -> 
56+                     val  properties =  library.resolve(" library.properties" 
57+                     val  name =  findNameInProperties(properties) ? :  library.name
58+ 
59+                     val  libraryExamples =  getSketches(library.resolve(" examples" 
60+                     Sketch .Companion .Folder (
61+                         type =  " folder" 
62+                         name =  name,
63+                         path =  library.absolutePath,
64+                         mode =  " java" 
65+                         children =  libraryExamples?.children ? :  emptyList(),
66+                         sketches =  libraryExamples?.sketches ? :  emptyList()
67+                     )
68+                 } ? :  emptyList()
69+             val  javaModeLibraries =  Sketch .Companion .Folder (
70+                 type =  " folder" 
71+                 name =  " Libraries" 
72+                 path =  " $javaMode /libraries" 
73+                 mode =  " java" 
74+                 children =  javaModeLibrariesExamples,
75+                 sketches =  emptyList()
76+             )
77+ 
78+             val  contributedLibraries =  sketchbookFolder.resolve(" libraries" 
79+                 .listFiles{ it.isDirectory }
80+                 ?.map { library -> 
81+                     val  properties =  library.resolve(" library.properties" 
82+                     val  name =  findNameInProperties(properties) ? :  library.name
83+                     //  Get library name from library.properties if it exists
84+                     val  libraryExamples =  getSketches(library.resolve(" examples" 
85+                     Sketch .Companion .Folder (
86+                         type =  " folder" 
87+                         name =  name,
88+                         path =  library.absolutePath,
89+                         mode =  " java" 
90+                         children =  libraryExamples?.children ? :  emptyList(),
91+                         sketches =  libraryExamples?.sketches ? :  emptyList()
92+                     )
93+                 } ? :  emptyList()
94+ 
95+             val  contributedLibrariesFolder =  Sketch .Companion .Folder (
96+                 type =  " folder" 
97+                 name =  " Contributed Libraries" 
98+                 path =  sketchbookFolder.resolve(" libraries" 
99+                 mode =  " java" 
100+                 children =  contributedLibraries,
101+                 sketches =  emptyList()
102+             )
103+ 
104+             val  contributedExamples =  sketchbookFolder.resolve(" examples" 
105+                 .listFiles{ it.isDirectory }
106+                 ?.map {
107+                     val  properties =  it.resolve(" examples.properties" 
108+                     val  name =  findNameInProperties(properties) ? :  it.name
109+ 
110+                     val  sketches =  getSketches(it.resolve(" examples" 
111+                     Sketch .Companion .Folder (
112+                         type =  " folder" 
113+                         name,
114+                         path =  it.absolutePath,
115+                         mode =  " java" 
116+                         children =  sketches?.children ? :  emptyList(),
117+                         sketches =  sketches?.sketches ? :  emptyList(),
118+                     )
119+                 }
120+                 ? :  emptyList()
121+             val  contributedExamplesFolder =  Sketch .Companion .Folder (
122+                 type =  " folder" 
123+                 name =  " Contributed Examples" 
124+                 path =  sketchbookFolder.resolve(" examples" 
125+                 mode =  " java" 
126+                 children =  contributedExamples,
127+                 sketches =  emptyList()
128+             )
129+ 
130+             val  json =  serializer.encodeToString(javaModeExamples +  javaModeLibraries +  contributedLibrariesFolder +  contributedExamplesFolder)
131+             println (json)
132+         }
133+ 
134+         private  fun  findNameInProperties (properties :  File ): String?  {
135+             if  (! properties.exists()) return  null 
136+ 
137+             return   properties.readLines().firstNotNullOfOrNull { line -> 
138+                 line.split(" =" =  2 )
139+                     .takeIf  { it.size ==  2  &&  it[0 ].trim() ==  " name" 
140+                     ?.let  { it[1 ].trim() }
141+             }
142+         }
143+     }
144+ }
0 commit comments