예제 #1
0
파일: main.go 프로젝트: BurntSushi/goim
func usage() {
	pef("goim is a tool for interacting with a local copy of IMDB.\n")
	pef("Usage:\n\n    goim {command} [flags] [arguments]\n")
	pef("Use 'goim help {command}' for more details on {command}.\n")

	fun.Sort(func(c1, c2 *command) bool { return c1.name < c2.name }, commands)

	pef("A list of the main commands:\n")
	tabw := tabwriter.NewWriter(os.Stderr, 0, 0, 4, ' ', 0)
	for _, c := range commands {
		if c.name == "ftp" || c.other {
			continue
		}
		fmt.Fprintf(tabw, "    %s\t%s\n", c.name, c.shortHelp)
	}
	tabw.Flush()
	pef("")

	pef("A list of other commands:\n")
	for _, c := range commands {
		if c.name == "ftp" || !c.other {
			continue
		}
		fmt.Fprintf(tabw, "    %s\t%s\n", c.name, c.shortHelp)
	}
	tabw.Flush()
	pef("")
	os.Exit(1)
}
예제 #2
0
파일: commands.go 프로젝트: BurntSushi/goim
func init() {
	less := func(f1, f2 string) bool { return f1 < f2 }
	fields := fun.QuickSort(less, fun.Keys(qualifiedColumns)).([]string)
	sortFields := strings.Join(fields, ", ")
	genres := strings.Join(imdb.EnumGenres, ", ")
	mpaas := strings.Join(imdb.EnumMPAA, ", ")

	commands = []command{
		{
			"movie", nil, false,
			"Restricts results to only include movies. Note that this may " +
				"be combined with other entity types to form a disjunction.",
			func(s *Searcher, v string) error {
				s.Entity(imdb.EntityMovie)
				return nil
			},
		},
		{
			"tvshow", nil, false,
			"Restricts results to only include TV shows. Note that this may " +
				"be combined with other entity types to form a disjunction.",
			func(s *Searcher, v string) error {
				s.Entity(imdb.EntityTvshow)
				return nil
			},
		},
		{
			"episode", nil, false,
			"Restricts results to only include episodes. Note that this may " +
				"be combined with other entity types to form a disjunction.",
			func(s *Searcher, v string) error {
				s.Entity(imdb.EntityEpisode)
				return nil
			},
		},
		{
			"actor", nil, false,
			"Restricts results to only include actors. Note that this may " +
				"be combined with other entity types to form a disjunction.",
			func(s *Searcher, v string) error {
				s.Entity(imdb.EntityActor)
				return nil
			},
		},
		{
			"genre", nil, true,
			"Restricts results to only include entities matching the genre " +
				"given. Multiple genres will be combined disjunctively. " +
				"Available genres: " + genres,
			func(s *Searcher, v string) error {
				s.Genre(v)
				return nil
			},
		},
		{
			"mpaa", nil, true,
			"Restricts results to only include entities with the MPAA rating " +
				"given. Multiple MPAA ratings will be combined " +
				"disjunctively. Available MPAA ratings: " + mpaas,
			func(s *Searcher, v string) error {
				s.MPAA(v)
				return nil
			},
		},
		{
			"credits", nil, true,
			"A sub-search for media entities that restricts results to " +
				"only actors media item returned from this sub-search.",
			func(s *Searcher, v string) error {
				return addSub(s, "credits", v, s.Credits)
			},
		},
		{
			"cast", nil, true,
			"A sub-search for cast entities that restricts results to " +
				"only media entities in which the cast member appeared.",
			func(s *Searcher, v string) error {
				return addSub(s, "cast", v, s.Cast)
			},
		},
		{
			"show", nil, true,
			"A sub-search for TV shows that restricts results to " +
				"only episodes in the TV show.",
			func(s *Searcher, v string) error {
				return addSub(s, "show", v, s.Tvshow)
			},
		},
		{
			"debug", nil, false,
			"When enabled, the SQL queries used in the search will be logged " +
				"to stderr.",
			func(s *Searcher, v string) error {
				s.debug = true
				return nil
			},
		},
		{
			"id", []string{"atom"}, true,
			"Precisely selects a single identity with the atom identifier " +
				"given. e.g., {id:123} returns the entity with id 123." +
				"Note that one SHOULD NOT rely on any specific atom " +
				"identifier to always correspond to a specific entity, since " +
				"identifiers can (sadly) change when updating your database.",
			func(s *Searcher, v string) error {
				n, err := strconv.Atoi(v)
				if err != nil {
					return ef("Invalid integer '%s' for atom id: %s", v, err)
				}
				s.Atom(imdb.Atom(n))
				return nil
			},
		},
		{
			"years", []string{"year"}, true,
			"Only show search results for the year or years specified. " +
				"e.g., {1990-1999} only shows movies in the 90s.",
			func(s *Searcher, v string) error {
				return addRange(v, s.Years)
			},
		},
		{
			"rank", nil, true,
			"Only show search results with the rank or ranks specified. " +
				"e.g., {70-} only shows entities with a rank of 70 or " +
				"better. Ranks are on a scale of 0 to 100, where 100 is the " +
				"best.",
			func(s *Searcher, v string) error {
				return addRange(v, s.Ranks)
			},
		},
		{
			"votes", nil, true,
			"Only show search results with ranks that have the vote count " +
				"specified. e.g., {10000-} only shows entities with a rank " +
				"that has 10,000 or more votes.",
			func(s *Searcher, v string) error {
				return addRange(v, s.Votes)
			},
		},
		{
			"billing", []string{"billed"}, true,
			"Only show search results with credits with the billing position " +
				"specified. e.g., {1-5} only shows movies where the actor " +
				"was in the top 5 billing order (or only shows actors of a " +
				"movie in the top 5 billing positions).",
			func(s *Searcher, v string) error {
				return addRange(v, s.Billed)
			},
		},
		{
			"seasons", []string{"s"}, true,
			"Only show search results for the season or seasons specified. " +
				"e.g., {seasons:1} only shows episodes from the first season " +
				"of a TV show. Note that this only filters episodes---movies " +
				"and TV shows are still returned otherwise.",
			func(s *Searcher, v string) error {
				return addRange(v, s.Seasons)
			},
		},
		{
			"episodes", []string{"e"}, true,
			"Only show search results for the season or seasons specified. " +
				"e.g., {episodes:1-5} only shows the first five episodes of " +
				"a of a season. Note that this only filters " +
				"episodes---movies and TV shows are still returned otherwise.",
			func(s *Searcher, v string) error {
				return addRange(v, s.Episodes)
			},
		},
		{
			"notv", nil, false,
			"Removes 'made for TV' movies from the search results.",
			func(s *Searcher, v string) error {
				s.NoTvMovies()
				return nil
			},
		},
		{
			"novideo", nil, false,
			"Removes 'made for video' movies from the search results.",
			func(s *Searcher, v string) error {
				s.NoVideoMovies()
				return nil
			},
		},
		{
			"similar", nil, true,
			"Sets the threshold at which to return results from a fuzzy text " +
				"search. Results scoring below this threshold are omitted. " +
				"Note that setting this value too low can dramatically " +
				"increase the search time.",
			func(s *Searcher, v string) error {
				n, err := strconv.ParseFloat(v, 64)
				if err != nil {
					return ef("Invalid float '%s' for similar: %s", v, err)
				}
				s.SimilarThreshold(n)
				return nil
			},
		},
		{
			"limit", nil, true,
			"Specifies a limit on the total number of search results returned.",
			func(s *Searcher, v string) error {
				n, err := strconv.Atoi(v)
				if err != nil {
					return ef("Invalid integer '%s' for limit: %s", v, err)
				}
				s.Limit(int(n))
				return nil
			},
		},
		{
			"sort", nil, true,
			"Sorts the search results according to the field given. It may " +
				"be specified multiple times for more specific sorting. Note " +
				"that this doesn't really work with fuzzy searching, since " +
				"results are always sorted by their similarity with the " +
				"query in a fuzzy search. e.g., {sort:episode desc} sorts " +
				"episode in descending (biggest to smallest) order. " +
				"Valid sort fields: " + sortFields + ".",
			func(s *Searcher, v string) error {
				fields := strings.Fields(v)
				if len(fields) != 2 {
					return ef("Invalid sort format "+
						"(must have field and order): '%s'", v)
				}
				s.Sort(fields[0], fields[1])
				return nil
			},
		},
	}

	// Add synonyms of commands to the map of commands.
	for _, cmd := range commands {
		allCommands[cmd.name] = cmd
		for _, synonym := range cmd.synonyms {
			allCommands[synonym] = cmd
		}
		Commands = append(Commands, Command{
			Name:        cmd.name,
			Synonyms:    cmd.synonyms,
			Description: cmd.description,
		})
	}
	fun.Sort(func(c1, c2 Command) bool { return c1.Name < c2.Name }, Commands)
}