11package desktop
22
33import (
4- "errors"
54 "fmt"
5+ "strconv"
66 "strings"
77
8- "github.com/AmadlaOrg/LibraryUtils/location "
8+ "github.com/AmadlaOrg/LibraryUtils/pointer "
99)
1010
11- type IDesktop interface {}
11+ type IDesktop interface {
12+ Build (desktop * Desktop ) (string , error )
13+ }
14+
1215type SDesktop struct {
1316 builder strings.Builder
1417}
@@ -22,7 +25,7 @@ const (
2225// Params:
2326// - 🖥️ desktop:
2427// - 📍 location:
25- func (service * SDesktop ) Build (desktop * Desktop , location * location. Application ) (string , error ) {
28+ func (service * SDesktop ) Build (desktop * Desktop ) (string , error ) {
2629 var (
2730 sectionNames []string
2831 )
@@ -38,9 +41,9 @@ func (service *SDesktop) Build(desktop *Desktop, location *location.Application)
3841 if section .Title == nil ||
3942 * section .Title == "" ||
4043 * section .Title == defaultDesktopSectionName {
41- thisSectionName = fmt .Sprintf ("[%s]" , defaultDesktopSectionName )
44+ thisSectionName = fmt .Sprintf ("[%s]\n " , defaultDesktopSectionName )
4245 } else {
43- thisSectionName = fmt .Sprintf ("[%s]" , * section .Title )
46+ thisSectionName = fmt .Sprintf ("[%s]\n " , * section .Title )
4447 }
4548
4649 service .builder .WriteString (thisSectionName )
@@ -49,125 +52,100 @@ func (service *SDesktop) Build(desktop *Desktop, location *location.Application)
4952 //
5053 // Name
5154 //
52- if section .Names == nil {
53- return "" , errors .New ("no section names" )
55+ err := service .processContent ("Name" , section .Names , true )
56+ if err != nil {
57+ return "" , err
5458 }
5559
56- service .processContent ("Name" , section .Names )
57-
5860 //
5961 // GenericNames
6062 //
61- service .processContent ("GenericName" , section .GenericNames )
63+ _ = service .processContent ("GenericName" , section .GenericNames , false )
6264
6365 //
6466 // Comments
6567 //
66- service .processContent ("Comment" , section .Comments )
68+ _ = service .processContent ("Comment" , section .Comments , false )
6769
6870 //
6971 // Keywords
7072 //
71- service .processContent ("Keyword " , section .Keywords )
73+ _ = service .processContent ("Keywords " , section .Keywords , false )
7274
7375 //
7476 // Version
7577 //
76- if section .Version == nil {
77- service .builder .WriteString ("Version=1.0" )
78- } else {
79- service .builder .WriteString (fmt .Sprintf ("Version=%s" , * section .Version ))
80- }
78+ service .processPropertyDefault ("Version" , section .Version , "1.0" )
8179
8280 //
8381 // X-AppVersion
8482 //
83+ err = service .processRequiredProperty ("X-AppVersion" , section .XAppVersion )
84+ if err != nil {
85+ return "" , err
86+ }
8587
86- }
88+ //
89+ // Icon
90+ //
91+ service .processNotRequiredProperty ("Icon" , section .Icon )
92+
93+ //
94+ // Categories
95+ //
96+ _ = service .processList ("Categories" , section .Categories , false )
97+
98+ //
99+ // x-kde-protocols
100+ //
101+ _ = service .processCommaList ("X-KDE-Protocols" , section .XKDEProtocols , false )
87102
88- // TODO: If Kali Linux: /usr/share/kali-menu/exec-in-shell "{appName} -h"
89-
90- /*
91- cat /usr/share/kali-menu/exec-in-shell
92- #!/usr/bin/env sh
93-
94- echo "$ $@"
95- eval $@
96-
97- USER=${USER:-$(whoami)}
98- SHELL=${SHELL:-$(getent passwd $USER | cut -d: -f7)}
99- ${SHELL:-bash} -i
100- */
101- /*
102- $ cat /usr/share/kali-menu/applications/kali-scapy.desktop
103-
104- [Desktop Entry]
105- Name=scapy
106- Comment=Interactive packet manipulation tool
107- Encoding=UTF-8
108- Exec=/usr/share/kali-menu/exec-in-shell "scapy"
109- Icon=kali-scapy
110- StartupNotify=false
111- Terminal=true
112- Type=Application
113- Categories=09-sniffing-spoofing;
114- X-Kali-Package=python3-scapy
115- */
116-
117- /*var
118- b.WriteString("INSERT INTO ")
119- b.WriteString(table.Name)
120- b.WriteString(" (")
121- b.WriteString(strings.Join(columnNames, ", "))
122- b.WriteString(") VALUES (")
123- b.WriteString(strings.Join(valuesPlaceholder, ", "))
124- b.WriteString(");")
125- b.String()
126-
127- execPath := filepath.Join(binHome, appName)
128-
129- // TODO: Maybe check if svg or png is supported
130- iconPath := filepath.Join(dataHome, "icon.svg")
131-
132- d := `[Desktop Entry]
133- Name=%s
134- Name[fr]=%s
135- GenericName=%s
136- GenericName[fr]=%s
137- Comment=%s
138- Comment[fr]=%s
139- Keywords=%s
140- Keywords[fr]=%s
141- Encoding=UTF-8
142- Exec=%s
143- Version=%s
144- Icon=%s
145- Terminal=true
146- Type=Application
147- Categories=Development;Utility;
148- X-KDE-Protocols=%s`
149-
150- // TODO:
151- // Version= ??
152-
153- // TODO:
154- // X-KDE-Protocols=ftp,http,https,mms,rtmp
155-
156- // MimeType:
157- // application/x-yaml
158- // text/yaml
159- // application/json
160- //
161- // Hery:
162- // application/json+hery
163- // application/x-yaml+hery
164- // text/yaml_hery
165-
166- var buildDesktop = fmt.Sprintf(desktop, appName, comment, execPath, version, iconPath)
167- if mimeType != nil {
168- mimeTypeEntry := fmt.Sprintf("\nMimeType=%s;", *mimeType)
169- buildDesktop = fmt.Appendln(buildDesktop, mimeTypeEntry)
170- }*/
103+ //
104+ // Encoding
105+ //
106+ service .processNotRequiredProperty ("Encoding" , section .Encoding )
107+
108+ //
109+ // Terminal
110+ //
111+ service .processPropertyDefault (
112+ "Terminal" ,
113+ pointer .ToPtr (strconv .FormatBool (section .Terminal )),
114+ "true" )
115+
116+ //
117+ // Type
118+ //
119+ if section .Type == nil || * section .Type == "" {
120+ section .Type = (* Type )(pointer .ToPtr ("Application" ))
121+ }
122+
123+ service .builder .WriteString (fmt .Sprintf ("Type=%s\n " , string (* section .Type )))
124+ if * section .Type == ApplicationType {
125+ //
126+ // Exec
127+ //
128+ err = service .processRequiredProperty ("Exec" , & section .Exec )
129+ if err != nil {
130+ return "" , err
131+ }
132+ } else if * section .Type == LinkType {
133+ //
134+ // Url
135+ //
136+ err = service .processRequiredProperty ("Url" , & section .URL )
137+ if err != nil {
138+ return "" , err
139+ }
140+ } else if * section .Type == DirectoryType {
141+ // TODO:
142+ }
143+
144+ //
145+ // MimeType
146+ //
147+ _ = service .processList ("MimeType" , section .MimeType , false )
148+ }
171149
172150 return service .builder .String (), nil
173151}
@@ -177,12 +155,120 @@ func (service *SDesktop) Build(desktop *Desktop, location *location.Application)
177155// Params:
178156// - 🏠 propertyName:
179157// - 💎 contentValues:
180- func (service * SDesktop ) processContent (propertyName string , contentValues * []Content ) {
158+ // - 🙏 need:
159+ func (service * SDesktop ) processContent (propertyName string , contentValues * []Content , isNeeded bool ) error {
160+ var (
161+ isSet = false
162+ isSetWithLang = false
163+ )
164+
181165 for _ , value := range * contentValues {
182166 if value .Language == nil {
183- service .builder .WriteString (fmt .Sprintf ("%s=%s" , propertyName , value .Value ))
167+ isSet = true
168+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , value .Value ))
184169 } else {
185- service .builder .WriteString (fmt .Sprintf ("%s[%s]=%s" , propertyName , * value .Language , value .Value ))
170+ isSetWithLang = true
171+ service .builder .WriteString (fmt .Sprintf ("%s[%s]=%s\n " , propertyName , * value .Language , value .Value ))
186172 }
187173 }
174+
175+ if isNeeded {
176+ if ! isSet && ! isSetWithLang {
177+ return fmt .Errorf ("%s not set" , propertyName )
178+ } else if ! isSet {
179+ return fmt .Errorf (
180+ "%s is set with specific language but not set without specific language" ,
181+ propertyName ,
182+ )
183+ }
184+ }
185+
186+ return nil
187+ }
188+
189+ // processPropertyDefault
190+ //
191+ // Params:
192+ // - 🏠 propertyName:
193+ // - 💎 contentValue:
194+ // - ⚠️ defaultValue:
195+ func (service * SDesktop ) processPropertyDefault (propertyName string , contentValue * string , defaultValue string ) {
196+ if contentValue == nil || * contentValue == "" {
197+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , defaultValue ))
198+ } else {
199+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , * contentValue ))
200+ }
201+ }
202+
203+ // processRequiredProperty
204+ //
205+ // Params:
206+ // - 🏠 propertyName:
207+ // - 💎 contentValue:
208+ func (service * SDesktop ) processRequiredProperty (propertyName string , contentValue * string ) error {
209+ if contentValue != nil && * contentValue != "" {
210+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , * contentValue ))
211+ return nil
212+ } else {
213+ return fmt .Errorf ("%s is required" , propertyName )
214+ }
215+ }
216+
217+ // processNotRequiredProperty
218+ //
219+ // Params:
220+ // - 🏠 propertyName:
221+ // - 💎 contentValue:
222+ func (service * SDesktop ) processNotRequiredProperty (propertyName string , contentValue * string ) {
223+ if contentValue != nil && * contentValue != "" {
224+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , * contentValue ))
225+ }
226+ }
227+
228+ // processList
229+ //
230+ // Params:
231+ // - 🏠 propertyName:
232+ // - 👑 items:
233+ // - 🙏 need:
234+ func (service * SDesktop ) processList (propertyName string , items * []List , isNeeded bool ) error {
235+ if isNeeded && (items == nil || len (* items ) == 0 ) {
236+ return fmt .Errorf ("%s is empty" , propertyName )
237+ }
238+
239+ if items != nil && len (* items ) > 0 {
240+ // Convert []List to []string
241+ stringItems := make ([]string , len (* items ))
242+ for i , item := range * items {
243+ stringItems [i ] = string (item ) // Convert List to string
244+ }
245+
246+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , strings .Join (stringItems , ";" )))
247+ }
248+
249+ return nil
250+ }
251+
252+ // processCommaList
253+ //
254+ // Params:
255+ // - 🏠 propertyName:
256+ // - 👑 items:
257+ // - 🙏 need:
258+ func (service * SDesktop ) processCommaList (propertyName string , items * []CommaList , isNeeded bool ) error {
259+ if isNeeded && (items == nil || len (* items ) == 0 ) {
260+ return fmt .Errorf ("%s is empty" , propertyName )
261+ }
262+
263+ if items != nil && len (* items ) > 0 {
264+ // Convert []List to []string
265+ stringItems := make ([]string , len (* items ))
266+ for i , item := range * items {
267+ stringItems [i ] = string (item ) // Convert List to string
268+ }
269+
270+ service .builder .WriteString (fmt .Sprintf ("%s=%s\n " , propertyName , strings .Join (stringItems , "," )))
271+ }
272+
273+ return nil
188274}
0 commit comments