package main import ( "fmt" "mime" "net/url" "os" "path/filepath" "strings" "github.com/AvengeMedia/DankMaterialShell/core/internal/log" "github.com/AvengeMedia/DankMaterialShell/core/internal/server/models" "github.com/spf13/cobra" ) var ( openMimeType string openCategories []string openRequestType string ) var openCmd = &cobra.Command{ Use: "open [target]", Short: "Open a file, URL, or resource with an application picker", Long: `Open a target (URL, file, or other resource) using the DMS application picker. By default, this opens URLs with the browser picker. You can customize the behavior with flags to handle different MIME types or application categories. Examples: dms open https://example.com # Open URL with browser picker dms open file.pdf # Open file (MIME auto-detected) dms open file.pdf --mime application/pdf # Override MIME detection dms open document.odt --category Office # Open with office applications`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { runOpen(args[0]) }, } func init() { rootCmd.AddCommand(openCmd) openCmd.Flags().StringVar(&openMimeType, "mime", "", "MIME type for filtering applications") openCmd.Flags().StringSliceVar(&openCategories, "category", []string{}, "Application categories to filter (e.g., WebBrowser, Office, Graphics)") openCmd.Flags().StringVar(&openRequestType, "type", "url", "Request type (url, file, or custom)") _ = openCmd.RegisterFlagCompletionFunc("type", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return []string{"url", "file", "custom"}, cobra.ShellCompDirectiveNoFileComp }) } func detectMimeFromPath(path string) string { ext := filepath.Ext(path) if ext == "" { return "" } return mime.TypeByExtension(ext) } func runOpen(target string) { actualTarget := target detectedMimeType := openMimeType detectedRequestType := openRequestType log.Infof("Processing target: %s", target) switch { case isScheme(target, "file://"): parsedURL, err := url.Parse(target) if err == nil { actualTarget = parsedURL.Path } if abs, err := filepath.Abs(actualTarget); err == nil { actualTarget = abs } if detectedRequestType == "url" || detectedRequestType == "" { detectedRequestType = "file" } if detectedMimeType == "" { detectedMimeType = detectMimeFromPath(actualTarget) } log.Infof("Detected file:// URI, absolute path: %s", actualTarget) case isScheme(target, "http://"), isScheme(target, "https://"), isScheme(target, "dms://"): if detectedRequestType == "" { detectedRequestType = "url" } log.Infof("Detected URL: %s", target) default: if _, err := os.Stat(target); err != nil { break } if abs, err := filepath.Abs(target); err == nil { actualTarget = abs } if detectedRequestType == "url" || detectedRequestType == "" { detectedRequestType = "file" } if detectedMimeType == "" { detectedMimeType = detectMimeFromPath(actualTarget) } log.Infof("Detected local file path: %s", actualTarget) } params := map[string]any{ "target": actualTarget, } if detectedMimeType != "" { params["mimeType"] = detectedMimeType } if len(openCategories) > 0 { params["categories"] = openCategories } if detectedRequestType != "" { params["requestType"] = detectedRequestType } method := "apppicker.open" if detectedMimeType == "" && len(openCategories) == 0 && (isScheme(target, "http://") || isScheme(target, "https://") || isScheme(target, "dms://")) { method = "browser.open" params["url"] = target } req := models.Request{ ID: 1, Method: method, Params: params, } log.Infof("Sending request - Method: %s, Params: %+v", method, params) if err := sendServerRequestFireAndForget(req); err != nil { fmt.Println("DMS is not running. Please start DMS first.") os.Exit(1) } log.Infof("Request sent successfully") } func isScheme(target, prefix string) bool { return strings.HasPrefix(target, prefix) }