func DoCollection(c *cli.Context) { useOptions(c) args := c.Args() if len(args) == 0 { term.Println("Too few arguments") return } name := args[0] collection, err := account.GetCollectionByName(name) if err == nil { term.Printf("Collection %s exists:\n", collection.CollectionName) if len(args) > 1 { term.Println("(Column arguments ignored)") } term.Section() showCollectionInfo(collection) return } schema, err := schemaWithColumns(args[1:]) if err != nil { term.Println(err.Error()) return } createCollection(name, schema) }
func selectSubdomain(appID string, required bool) { app, _ := account.GetAppByID(appID) log.Debugf("Subdomain app: %v", app) for { if required { app.HostingSubdomain = term.GetString("Choose a *.appstax.io subdomain for hosting") } else { term.Println("Choose a *.appstax.io subdomain for hosting:") term.Println("(Leave this blank if you wish to decide this later.)") app.HostingSubdomain = term.GetString("Subdomain") } if app.HostingSubdomain != "" { err1 := account.SaveApp(app) if err1 != nil { term.Println(err1.Error()) } err2 := account.AddCorsOrigin(appID, fmt.Sprintf("http://%s.appstax.io", app.HostingSubdomain)) if err2 != nil { term.Println(err2.Error()) } if err1 == nil && err2 == nil { term.Printf("Successfully configured %s.appstax.io\n", app.HostingSubdomain) return } } else if !required { return } } }
func DoDeploy(c *cli.Context) { useOptions(c) if !config.Exists() { term.Println("Can't find appstax.conf. Run 'appstax init' to initialize before deploying.") return } args := c.Args() if len(args) == 0 { term.Println("Too few arguments. Usage: appstax deploy server|public|all") return } target := args[0] loginIfNeeded() switch target { case "public": deployPublic() case "server": deployServer() case "all": deployPublic() deployServer() } }
func DoFind(c *cli.Context) { useOptions(c) args := c.Args() if len(args) == 0 { term.Println("Too few arguments") return } collection, err := account.GetCollectionByName(args[0]) if err != nil { term.Println(err.Error()) return } filter := "" if len(args) > 1 { filter = args[1] } objects, err := account.GetObjects(collection.CollectionName, filter) if err != nil { term.Println(err.Error()) return } columns := collection.SortedColumnNames() rows := objectsAsStringTable(columns, objects) term.Layout(false) term.PrintTable(columns, rows) }
func DoRelation(c *cli.Context) { useOptions(c) args := c.Args() if len(args) < 2 { term.Println("Too few arguments") return } from := args[0] to := args[1] relation, err := makeRelationFromArgs(from, to) if err != nil { term.Println(err.Error()) return } _, err = account.SaveNewRelation(relation) if err != nil { term.Println(err.Error()) return } term.Println("Succesfully added " + relation.Description()) }
func DoServe(c *cli.Context) { useOptions(c) publicDir := config.ResolvePath(config.Read().PublicDir) term.Println("Serving your public directory at http://localhost:9000/") term.Println("Press Ctrl-C to stop.") term.Section() http.Handle("/", http.FileServer(http.Dir(publicDir))) http.ListenAndServe(":9000", nil) }
func loginIfNeeded() { if session.ReadSessionID() == "" { term.Section() term.Println("Please log in:") login() } }
func login() { for { email := term.GetString("Email") password := term.GetPassword("Password") sessionID, userID, accountID, err := account.Login(email, password) if err != nil { term.Section() term.Println(err.Error()) } else { writeSession(sessionID, userID, accountID) term.Section() term.Println(fmt.Sprintf("Successfully logged in as '%s'", email)) return } } }
func selectApp() (account.App, error) { apps, _ := account.GetUserApps() selected := -1 if len(apps) == 0 { term.Section() term.Println("You have not created any apps yet!") term.Println("Log in on https://appstax.com and create one before you proceed.") } else { term.Section() term.Println("Choose which app to configure:") for i, app := range apps { term.Printf(" %d) %s\n", i+1, app.AppName) } term.Section() for selected < 0 || selected >= len(apps) { selected = -1 + term.GetInt(fmt.Sprintf("Please select (1-%d)", len(apps))) } } return apps[selected], nil }
func deployServer() { dir := config.ResolvePath(config.Read().ServerDir) term.Section() if !directoryExists(dir) { term.Println("Directory does not exist: " + dir) term.Println("Skipping server deploy") return } term.Println("Packaging server files for upload...") archive, bytes, err := hosting.PrepareArchive(dir) if err != nil { term.Section() term.Println(err.Error()) return } term.Printf("Uploading %.2f MB...\n", float64(bytes)/(1024.0*1024.0)) progress := term.ShowProgressBar(bytes) err = hosting.UploadServer(archive, progress) if err != nil { progress.Finish() term.Section() term.Println("Error deploying server: " + err.Error()) } else { progress.Finish() term.Section() term.Println("Server deploy completed!") } }
func DoSignup(c *cli.Context) { useOptions(c) term.Println("By signing up you agree to our terms of service:") term.Println("https://appstax.com/admin/#/tos") term.Section() for { firstName := term.GetString("First name") lastName := term.GetString("Last name") email := term.GetString("Email") password := term.GetPassword("Password") sessionID, userID, accountID, err := account.Signup(firstName, lastName, email, password) if err != nil { term.Section() term.Println(err.Error()) } else { writeSession(sessionID, userID, accountID) term.Section() term.Println(fmt.Sprintf("Account created for '%s'", email)) return } } }
func DoInit(c *cli.Context) { useOptions(c) loginIfNeeded() app, err := selectApp() if err != nil { return } tpl := selectTemplate() publicDir := "./public" serverDir := "./server" writeConfig(app, publicDir, serverDir) if !strings.HasPrefix(tpl.Name, "ios/") { createPublicDir() } createServerDir() if tpl.Name != "none" { term.Section() term.Println("Setting up template... ") template.Install(tpl) term.Println("Done.") } if !strings.HasPrefix(tpl.Name, "ios/") { term.Section() selectSubdomain(app.AppID, false) } term.Section() term.Println("All done!") if !strings.HasPrefix(tpl.Name, "ios/") { term.Println("Now run 'appstax deploy' when you are ready to upload your files.") } }
func deployPublic() { selectSubdomainIfNeeded() dir := config.ResolvePath(config.Read().PublicDir) term.Section() if !directoryExists(dir) { term.Println("Directory does not exist: " + dir) term.Println("Skipping public deploy") return } term.Println("Packaging public files for upload...") archive, bytes, _ := hosting.PrepareArchive(dir) term.Printf("Uploading %.2f MB...\n", float64(bytes)/(1024.0*1024.0)) progress := term.ShowProgressBar(bytes) err := hosting.UploadStatic(archive, progress) if err != nil { progress.Finish() term.Section() term.Println("Error deploying public files: " + err.Error()) } else { progress.Finish() term.Section() term.Println("Public deploy completed!") } }
func selectTemplate() template.Template { templates := template.All() term.Section() term.Println("Choose a template for you app:") for i, template := range templates { term.Printf(" %d) %s\n", i+1, template.Label) } term.Section() for { selected := -1 + term.GetInt(fmt.Sprintf("Please select (1-%d)", len(templates))) if selected >= 0 && selected < len(templates) { return templates[selected] } } }
func createCollection(name string, schema map[string]interface{}) { app, _ := account.GetCurrentApp() collection := account.Collection{ CollectionName: name, AppID: app.AppID, AccountID: session.ReadAccountID(), Schema: schema, } collection, err := account.SaveNewCollection(collection) if err != nil { term.Println(err.Error()) } else { term.Printf("Collection %s created successfully!\n", collection.CollectionName) term.Section() showCollectionInfo(collection) } }
func DoOpen(c *cli.Context) { useOptions(c) dest := c.Args().First() log.Debugf("Open destination: %s", dest) url := "" message := "" switch dest { default: fallthrough case "deployed": app, err := account.GetCurrentApp() if err != nil { message = "Sorry, could not find a deployed app to open." } url = "http://" + app.HostingSubdomain + ".appstax.io" break case "admin": url = "http://appstax.com/admin/#/dashboard" break case "local": url = "http://localhost:9000/" break } if url != "" { term.Printf("Opening %s in your browser.\n", url) err := open.Start(url) if err != nil { message = "Ooops! Something went wrong." } } if message != "" { term.Section() term.Println(message) } }
func DoInfo(c *cli.Context) { useOptions(c) loginIfNeeded() if !config.Exists() { term.Println("No app configured in current directory. (Missing appstax.conf)") } else { app, err := account.GetCurrentApp() if err != nil { term.Println("You don't have access to the currently selected app") } else { term.Println("App name: " + app.AppName) term.Println("Description: " + app.AppDescription) term.Println("App key: " + app.AppKey) term.Println("Collections: " + strings.Join(app.CollectionNames(), ", ")) term.Println("Hosting: " + account.FormatHostingUrl(app)) term.Section() } } user, err := account.GetUser() fail.Handle(err) term.Printf("Logged in as %s %s (%s)\n", user.FirstName, user.LastName, user.Email) }
func DoServer(c *cli.Context) { useOptions(c) if !config.Exists() { term.Println("Can't find appstax.conf. Run 'appstax init' to initialize before deploying.") return } loginIfNeeded() args := c.Args() if len(args) == 0 { term.Println("Too few arguments. Usage: appstax server create|delete|status|start|stop|log") return } operation := args[0] switch operation { case "create": selectSubdomainIfNeeded() accessCode := term.GetString("Please enter early access code") err := hosting.CreateServer(accessCode) if err == nil { term.Println("Server created successfully!") } else { term.Println("Error creating server:") term.Println(err.Error()) } case "delete": err := hosting.DeleteServer() if err == nil { term.Println("Server deleted!") } else { term.Println("Error deleting server:") term.Println(err.Error()) } case "status": status, err := hosting.GetServerStatus() if err == nil { term.Println("Server status: " + status.Status) } else { term.Println("Error getting server status:") term.Println(err.Error()) } case "start": err := hosting.SendServerAction(operation) if err == nil { term.Println("Server started!") } else { term.Println("Error starting server:") term.Println(err.Error()) } case "stop": err := hosting.SendServerAction(operation) if err == nil { term.Println("Server stopped!") } else { term.Println("Error stopping server:") term.Println(err.Error()) } case "log", "logs": nlines := int64(10) if len(args) >= 2 { n, err := strconv.ParseInt(args[1], 10, 64) if err == nil { nlines = n } } log, err := hosting.GetServerLog(nlines) if err == nil { term.Layout(false) term.Dump(log) } else { term.Println("Error getting server log:") term.Println(err.Error()) } default: term.Printf("Unknown server operation '%s'\n", operation) } }
func DoLogout(c *cli.Context) { session.Delete() term.Println("Logged out.") }