github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/docs/commands/open.md (about)

     1  # `open`
     2  
     3  > Open a file with a preferred handler
     4  
     5  ## Description
     6  
     7  `open` is a smart tool for reading files:
     8  
     9  1. It will read a file from disk or a HTTP(S) endpoints
    10  2. Detect the file type via file extension or HTTP header `Content-Type`
    11  3. It intelligently writes to STDOUT
    12    - If STDOUT is a TTY it will perform any transformations to render to the
    13      terminal (eg using inlining images)
    14    - If STDOUT is a pipe then it will write a byte stream with the relevant
    15      data-type
    16  4. If there are no open handlers then it will fallback to the systems default.
    17     eg `open` (on macOS, Linux), `open-xdg` (X11), etc.
    18  
    19  ## Usage
    20  
    21  ```
    22  open filename[.gz]|uri -> <stdout>
    23  ```
    24  
    25  ## Examples
    26  
    27  ```
    28  » open https://api.github.com/repos/lmorg/murex/issues -> foreach issue { out "$issue[number]: $issue[title]" }
    29  ```
    30  
    31  ## Detail
    32  
    33  ### File Extensions
    34  
    35  Supported file extensions are listed in `config` under the app and key names of
    36  **shell**, **extensions**.
    37  
    38  Unsupported file extensions are defaulted to generic, `*`.
    39  
    40  Files with a `.gz` extension are assumed to be gzipped and thus are are
    41  automatically expanded.
    42  
    43  ### MIME Types
    44  
    45  The `Content-Type` HTTP header is compared against a list of MIME types, which
    46  are stored in `config` under the app and key names of **shell**, **mime-types**.
    47  
    48  There is a little bit of additional logic to determine the Murex data-type to
    49  use should the MIME type not appear in `config`, as seen in the following code:
    50  
    51  ```go
    52  package lang
    53  
    54  import (
    55  	"regexp"
    56  	"strings"
    57  
    58  	"github.com/lmorg/murex/lang/types"
    59  )
    60  
    61  var rxMimePrefix = regexp.MustCompile(`^([-0-9a-zA-Z]+)/.*$`)
    62  
    63  // MimeToMurex gets the murex data type for a corresponding MIME
    64  func MimeToMurex(mimeType string) string {
    65  	mime := strings.Split(mimeType, ";")[0]
    66  	mime = strings.TrimSpace(mime)
    67  	mime = strings.ToLower(mime)
    68  
    69  	// Find a direct match. This is only used to pick up edge cases, eg text files used as images.
    70  	dt := mimes[mime]
    71  	if dt != "" {
    72  		return dt
    73  	}
    74  
    75  	// No direct match found. Fall back to prefix.
    76  	prefix := rxMimePrefix.FindStringSubmatch(mime)
    77  	if len(prefix) != 2 {
    78  		return types.Generic
    79  	}
    80  
    81  	switch prefix[1] {
    82  	case "text", "i-world", "message":
    83  		return types.String
    84  
    85  	case "audio", "music", "video", "image", "model":
    86  		return types.Binary
    87  
    88  	case "application":
    89  		if strings.HasSuffix(mime, "+json") {
    90  			return types.Json
    91  		}
    92  		return types.Generic
    93  
    94  	default:
    95  		// Mime type not recognized so lets just make it a generic.
    96  		return types.Generic
    97  	}
    98  
    99  }
   100  ```
   101  
   102  ### HTTP User Agent
   103  
   104  `open`'s user agent is the same as `get` and `post` and is configurable via
   105  `config` under they app **http**
   106  
   107  ```
   108  » config -> [http]
   109  {
   110      "cookies": {
   111          "Data-Type": "json",
   112          "Default": {
   113              "example.com": {
   114                  "name": "value"
   115              },
   116              "www.example.com": {
   117                  "name": "value"
   118              }
   119          },
   120          "Description": "Defined cookies to send, ordered by domain.",
   121          "Dynamic": false,
   122          "Global": false,
   123          "Value": {
   124              "example.com": {
   125                  "name": "value"
   126              },
   127              "www.example.com": {
   128                  "name": "value"
   129              }
   130          }
   131      },
   132      "default-https": {
   133          "Data-Type": "bool",
   134          "Default": false,
   135          "Description": "If true then when no protocol is specified (`http://` nor `https://`) then default to `https://`.",
   136          "Dynamic": false,
   137          "Global": false,
   138          "Value": false
   139      },
   140      "headers": {
   141          "Data-Type": "json",
   142          "Default": {
   143              "example.com": {
   144                  "name": "value"
   145              },
   146              "www.example.com": {
   147                  "name": "value"
   148              }
   149          },
   150          "Description": "Defined HTTP request headers to send, ordered by domain.",
   151          "Dynamic": false,
   152          "Global": false,
   153          "Value": {
   154              "example.com": {
   155                  "name": "value"
   156              },
   157              "www.example.com": {
   158                  "name": "value"
   159              }
   160          }
   161      },
   162      "insecure": {
   163          "Data-Type": "bool",
   164          "Default": false,
   165          "Description": "Ignore certificate errors.",
   166          "Dynamic": false,
   167          "Global": false,
   168          "Value": false
   169      },
   170      "redirect": {
   171          "Data-Type": "bool",
   172          "Default": true,
   173          "Description": "Automatically follow redirects.",
   174          "Dynamic": false,
   175          "Global": false,
   176          "Value": true
   177      },
   178      "timeout": {
   179          "Data-Type": "int",
   180          "Default": 10,
   181          "Description": "Timeout in seconds for `get` and `getfile`.",
   182          "Dynamic": false,
   183          "Global": false,
   184          "Value": 10
   185      },
   186      "user-agent": {
   187          "Data-Type": "str",
   188          "Default": "murex/1.7.0000 BETA",
   189          "Description": "User agent string for `get` and `getfile`.",
   190          "Dynamic": false,
   191          "Global": false,
   192          "Value": "murex/1.7.0000 BETA"
   193      }
   194  }
   195  ```
   196  
   197  ### Open Flags
   198  
   199  If the `open` builtin falls back to using the systems default (like `open-xdg`)
   200  then the only thing that gets passed is the path being opened. If the path is
   201  stdin then a temporary file will be created. If you want to pass command line
   202  flags to `open-xdg` (for example), then you need to call that command directly.
   203  In the case of macOS and some Linux systems, that might look like:
   204  
   205  ```
   206  exec open --flags filename
   207  ```
   208  
   209  ## See Also
   210  
   211  * [`*` (generic)](../types/generic.md):
   212    generic (primitive)
   213  * [`config`](../commands/config.md):
   214    Query or define Murex runtime settings
   215  * [`exec`](../commands/exec.md):
   216    Runs an executable
   217  * [`fexec` ](../commands/fexec.md):
   218    Execute a command or function, bypassing the usual order of precedence.
   219  * [`foreach`](../commands/foreach.md):
   220    Iterate through an array
   221  * [`get`](../commands/get.md):
   222    Makes a standard HTTP request and returns the result as a JSON object
   223  * [`getfile`](../commands/getfile.md):
   224    Makes a standard HTTP request and return the contents as Murex-aware data type for passing along Murex pipelines.
   225  * [`openagent`](../commands/openagent.md):
   226    Creates a handler function for `open`
   227  * [`out`](../commands/out.md):
   228    Print a string to the STDOUT with a trailing new line character
   229  * [`post`](../commands/post.md):
   230    HTTP POST request with a JSON-parsable return
   231  
   232  <hr/>
   233  
   234  This document was generated from [builtins/core/open/open_doc.yaml](https://github.com/lmorg/murex/blob/master/builtins/core/open/open_doc.yaml).