Ejemplo n.º 1
0
func (this Task) Verify(path string) bool {
	if this.IsBt() {
		fmt.Println("Verifying [BT]", path)
		if b, err := GetTorrentByHash(this.Cid); err != nil {
			fmt.Println(err)
			return false
		} else {
			if m, err := taipei.DecodeMetaInfo(b); err != nil {
				fmt.Println(err)
				return false
			} else {
				taipei.Iconv(m)
				taipei.SetEcho(true)
				g, err := taipei.VerifyContent(m, path)
				taipei.SetEcho(false)
				if err != nil {
					fmt.Println(err)
				}
				return g
			}
		}
	} else if strings.HasPrefix(this.URL, "ed2k://") {
		fmt.Println("Verifying [ED2K]", path)
		h, err := getEd2kHash(path)
		if err != nil {
			fmt.Println(err)
			return false
		}
		if !strings.EqualFold(h, getEd2kHashFromURL(this.URL)) {
			return false
		}
	}
	return true
}
Ejemplo n.º 2
0
func main() {
	initConf()
	flag.StringVar(&conf.Id, "login", conf.Id, "login account")
	flag.StringVar(&conf.Pass, "pass", conf.Pass, "password/passhash")
	flag.BoolVar(&printVer, "version", false, "print version")
	flag.BoolVar(&isDaemon, "d", false, "run as daemon/server")
	loop := flag.Bool("loop", false, "start daemon loop in background")
	close_fds := flag.Bool("close-fds", false, "close stdout,stderr,stdin")
	flag.Parse()
	if printVer {
		printVersion()
		return
	}
	var login = func() error {
		if err := ResumeSession(cookie_file); err != nil {
			if err = Login(conf.Id, conf.Pass); err != nil {
				return err
			}
			if err = SaveSession(cookie_file); err != nil {
				return err
			}
		}
		return nil
	}

	if isDaemon {
		cmd := exec.Command(os.Args[0], "-loop", "-close-fds")
		err := cmd.Start()
		if err != nil {
			glog.Fatalln(err)
		}
		cmd.Process.Release()
		// FIXME: find a proper way to detect daemon error and call cmd.Process.Kill().
		return
	}

	if *close_fds {
		os.Stdout.Close()
		os.Stderr.Close()
		os.Stdin.Close()
	}

	if *loop {
		go func() {
			if err := login(); err != nil {
				os.Exit(1)
			}
			GetGdriveId()
		}()
		daemonLoop()
		return
	}

	if err := login(); err != nil {
		os.Exit(1)
	}
	GetGdriveId()
	term := newTerm()
	defer term.Restore()
	{
		var err error
		insufficientArgErr := errors.New("Insufficient arguments.")
		noTasksMatchesErr := errors.New("No task matches.")
		var line string
		var cmds []string
		clearscr()
	LOOP:
		for {
			line, err = term.ReadLine()
			if err != nil {
				break
			}
			cmds = strings.Fields(line)
			if len(cmds) == 0 {
				continue
			}
			switch cmds[0] {
			case "ison":
				glog.V(2).Infoln(IsOn())
			case "me":
				fmt.Printf("%#v\n", *M.Account)
			case "relogin":
				if !IsOn() {
					if err = Login(conf.Id, conf.Pass); err != nil {
						glog.V(2).Infoln(err)
					} else if err = SaveSession(cookie_file); err != nil {
						glog.V(2).Infoln(err)
					}
				} else {
					fmt.Println("Already log on.")
				}
			case "saveconf":
				{
					conf.Pass = EncryptPass(conf.Pass)
					b, err := conf.save(conf_file)
					if err == nil {
						fmt.Printf("%s\n", b)
					}
				}
			case "loadconf":
				{
					if _, err = conf.load(conf_file); err == nil {
						fmt.Printf("%+v\n", conf)
					}
				}
			case "savesession":
				{
					if err := SaveSession(cookie_file); err != nil {
						fmt.Println(err)
					} else {
						fmt.Println("[done]")
					}
				}
			case "cls", "clear":
				clearscr()
			case "ls":
				ts, err := GetTasks()
				if err == nil {
					k := 0
					for i, _ := range ts {
						fmt.Printf("#%d %v\n", k, ts[i].Coloring())
						k++
					}
				} else {
					fmt.Println(err)
				}
			case "ld":
				ts, err := GetDeletedTasks()
				if err == nil {
					k := 0
					for i, _ := range ts {
						fmt.Printf("#%d %v\n", k, ts[i].Coloring())
						k++
					}
				} else {
					fmt.Println(err)
				}
			case "le":
				ts, err := GetExpiredTasks()
				if err == nil {
					k := 0
					for i, _ := range ts {
						fmt.Printf("#%d %v\n", k, ts[i].Coloring())
						k++
					}
				} else {
					fmt.Println(err)
				}
			case "lc":
				ts, err := GetCompletedTasks()
				if err == nil {
					k := 0
					for i, _ := range ts {
						fmt.Printf("#%d %v\n", k, ts[i].Coloring())
						k++
					}
				} else {
					fmt.Println(err)
				}
			case "ll":
				var ts []*Task
				ts, err = GetTasks()
				if err == nil {
					k := 0
					for i, _ := range ts {
						fmt.Printf("#%d %v\n", k, ts[i].Repr())
						k++
					}
				}
			case "head":
				var ts []*Task
				var num int = 10
				if len(cmds) > 1 {
					num, err = strconv.Atoi(cmds[1])
					if err != nil {
						num = 10
					}
				}
				ts, err = GetTasks()
				if len(ts) == 0 {
					err = errors.New("Empty task list")
				} else if len(ts) < num {
					num = len(ts)
				}
				if err == nil {
					k := 0
					for i, _ := range ts[:num] {
						fmt.Printf("#%d %v\n", k, ts[i].Coloring())
						k++
					}
				}
			case "cache_clean", "cc":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					switch cmds[1] {
					case "normal":
						M.InvalidateGroup(0)
					case "deleted":
						M.InvalidateGroup(1)
					case "purged":
						M.InvalidateGroup(2)
					case "invalid":
						M.InvalidateGroup(3)
					case "expired":
						M.InvalidateGroup(4)
					case "all":
						M.InvalidateAll()
					}
				}
			case "info":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						j := 0
						for i, _ := range ts {
							if ts[i].IsBt() {
								m, err := ts[i].FillBtList()
								fmt.Printf("#%d %v\n", j, ts[i].Repr())
								if err == nil {
									fmt.Printf("%v\n", m)
								}
							} else {
								fmt.Printf("#%d %v\n", j, ts[i].Repr())
							}
							j++
						}
					}
				}
			case "launch":
				var b []byte
				b, err = launchAria2cDaemon()
				if err == nil {
					fmt.Printf("%s\n", b)
				}
			case "status":
				var b []byte
				b, err = RPCStatus()
				if err == nil {
					fmt.Printf("%s\n", b)
				}
			case "kill":
				var s string
				force := false
				if len(cmds) >= 2 && (cmds[1] == "-9" || cmds[1] == "-f") {
					force = true
				}
				s, err = RPCShutdown(force)
				if err == nil {
					fmt.Println(s)
				}
			case "submit", "sub":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					pay := make(map[string]*struct {
						t *Task
						s string
					})
					for i, _ := range cmds[1:] {
						p := strings.Split(cmds[1:][i], "/")
						m, err := _find(p[0])
						if err == nil {
							for i, _ := range m {
								var filter string
								if len(p) == 1 {
									filter = `.*`
								} else {
									filter = p[1]
								}
								pay[m[i].Id] = &struct {
									t *Task
									s string
								}{m[i], filter}
							}
						}
					}
					for i, _ := range pay {
						if err = download(pay[i].t, pay[i].s, false, false, func(uri, filename string, echo bool) error {
							_, err := RPCAddTask(uri, filename)
							return err
						}); err != nil {
							fmt.Println(err)
						}
					}
					err = nil
				}
			case "verify":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if _, err = os.Stat(ts[i].TaskName); err != nil {
								fmt.Println(err)
								continue
							}
							fmt.Printf("Task verified? %v\n", ts[i].Verify(ts[i].TaskName))
						}
						err = nil
					}
				}
			case "dl", "download":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					pay := make(map[string]*struct {
						t *Task
						s string
					})
					del := false
					check := conf.CheckHash
					for i, _ := range cmds[1:] {
						if strings.HasPrefix(cmds[1:][i], "--") {
							switch cmds[1:][i][2:] {
							case "delete":
								del = true
							case "check":
								check = true
							case "no-check", "nocheck":
								check = false
							}
						} else {
							p := strings.Split(cmds[1:][i], "/")
							m, err := _find(p[0])
							if err == nil {
								for i, _ := range m {
									var filter string
									if len(p) == 1 {
										filter = `.*`
									} else {
										filter = p[1]
									}
									pay[m[i].Id] = &struct {
										t *Task
										s string
									}{m[i], filter}
								}
							}
						}
					}
					for i, _ := range pay {
						if err = download(pay[i].t, pay[i].s, true, check, dl); err != nil {
							fmt.Println(err)
						} else if del {
							if err = pay[i].t.Remove(); err != nil {
								fmt.Println(err)
							}
						}
					}
					err = nil
				}
			case "dt":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil { // TODO: improve find query
						for i, _ := range ts {
							if ts[i].IsBt() {
								if err = GetTorrentFileByHash(ts[i].Cid, ts[i].TaskName+".torrent"); err != nil {
									fmt.Println(err)
								}
							}
						}
						err = nil
					}
				} else {
					err = insufficientArgErr
				}
			case "ti":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil { // TODO: improve find query
						for i, _ := range ts {
							if ts[i].IsBt() {
								if b, err := GetTorrentByHash(ts[i].Cid); err != nil {
									fmt.Println(err)
								} else {
									if m, err := taipei.DecodeMetaInfo(b); err != nil {
										fmt.Println(err)
									} else {
										taipei.Iconv(m)
										fmt.Println(m)
									}
								}
							}
						}
						err = nil
					}
				} else {
					err = insufficientArgErr
				}
			case "add":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					req := cmds[1:]
					for j, _ := range req {
						if err = AddTask(req[j]); err != nil {
							fmt.Println(err)
						}
					}
					err = nil
				}
			case "rm", "delete":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if err = ts[i].Remove(); err != nil {
								fmt.Println(err)
							}
						}
						err = nil
					}
				}
			case "purge":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if err = ts[i].Purge(); err != nil {
								fmt.Println(err)
							}
						}
						err = nil
					}
				}
			case "readd":
				// re-add tasks from deleted or expired
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						ReAddTasks(ts)
					}
				} else {
					err = insufficientArgErr
				}
			case "delayall":
				{
					DelayAllTasks()
				}
			case "pause":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if err = ts[i].Pause(); err != nil {
								fmt.Println(err)
							}
						}
						err = nil
					}
				} else {
					err = insufficientArgErr
				}
			case "resume":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if err = ts[i].Resume(); err != nil {
								fmt.Println(err)
							}
						}
						err = nil
					}
				} else {
					err = insufficientArgErr
				}
			case "rename", "mv":
				if len(cmds) > 2 {
					// must be task id here
					if t, ok := M.Tasks[cmds[1]]; ok {
						t.Rename(strings.Join(cmds[2:], " "))
					} else {
						err = noTasksMatchesErr
					}
				} else {
					err = insufficientArgErr
				}
			case "delay":
				if len(cmds) < 2 {
					err = insufficientArgErr
				} else {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							if err = ts[i].Delay(); err != nil {
								fmt.Println(err)
							}
						}
						err = nil
					}
				}
			case "link":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						k := 0
						for i, _ := range ts {
							if !ts[i].IsBt() {
								fmt.Printf("#%d %s: %v\n", k, ts[i].Id, ts[i].LixianURL)
							} else {
								m, err := ts[i].FillBtList()
								if err == nil {
									fmt.Printf("#%d %s:\n", k, ts[i].Id)
									for j, _ := range m.Record {
										fmt.Printf("  #%d %s\n", j, m.Record[j].DownURL)
									}
								} else {
									fmt.Println(err)
								}
							}
							k++
						}
					}
				} else {
					err = insufficientArgErr
				}
			case "find":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						k := 0
						for i, _ := range ts {
							fmt.Printf("#%d %v\n", k, ts[i].Coloring())
							k++
						}
					}
				} else {
					fmt.Println(`pattern == "name=abc&group=completed&status=normal&type=bt"`)
					err = insufficientArgErr
				}
			case "st":
				{
				}
			case "rpc":
				{
				}
			case "play":
				if len(cmds) > 1 {
					var ts map[string]*Task
					if ts, err = find(cmds[1:]); err == nil {
						for i, _ := range ts {
							low, high, err := ts[i].GetVodURL()
							if err == nil {
								fmt.Printf("%s\n%s\n", low, high)
							}
						}
					}
				} else {
					err = insufficientArgErr
				}
			case "vod":
				if len(cmds) > 1 {
					var list interface{}
					for i, _ := range cmds[1:] {
						switch cmds[1:][i] {
						case "hist":
							list, err = GetHistoryPlayList()
						case "lx":
							list, err = GetLxtaskList()
						default:
							err = errors.New("Unkown vod command.")
						}
						if err == nil {
							fmt.Println(list)
						}
					}
				} else {
					err = insufficientArgErr
				}
			case "version":
				printVersion()
			case "update":
				err = ProcessTask(func(t *Task) {
					fmt.Printf("%s %s %sB/s %.2f%%\n", t.Id, fixedLengthName(t.TaskName, 32), t.Speed, t.Progress)
				})
			case "quit", "exit":
				break LOOP
			case "help":
				// TODO
			default:
				err = fmt.Errorf("Unrecognised command: %s", cmds[0])
			}
			if err != nil {
				fmt.Println(err)
			}
		}
	}
}