예제 #1
0
func (s *Server) init() error {
	//init maps
	s.state.Users = map[string]*realtime.User{}
	//will use a the local embed/ dir if it exists, otherwise will use the hardcoded embedded binaries
	s.files = http.HandlerFunc(s.serveFiles)
	s.static = ctstatic.FileSystemHandler()
	s.scraper = &scraper.Handler{Log: false}
	if err := s.scraper.LoadConfig(defaultSearchConfig); err != nil {
		log.Fatal(err)
	}
	s.state.SearchProviders = s.scraper.Config //share scraper config
	s.scraperh = http.StripPrefix("/search", s.scraper)

	s.engine = engine.New()

	//realtime
	s.rt = realtime.NewHandler()
	if err := s.rt.Add("state", &s.state); err != nil {
		log.Fatalf("State object not syncable: %s", err)
	}
	//realtime user events
	go func() {
		for user := range s.rt.UserEvents() {
			if user.Connected {
				s.state.Users[user.ID] = user
			} else {
				delete(s.state.Users, user.ID)
			}
			s.state.Update()
		}
	}()

	//configure engine
	c := engine.Config{
		DownloadDirectory: "./downloads",
		EnableUpload:      true,
		EnableSeeding:     false,
		AutoStart:         true,
	}
	if _, err := os.Stat(s.ConfigPath); err == nil {
		if b, err := ioutil.ReadFile(s.ConfigPath); err != nil {
			return fmt.Errorf("Read configuration error: %s", err)
		} else if err := json.Unmarshal(b, &c); err != nil {
			return fmt.Errorf("Malformed configuration: %s", err)
		}
	}
	if err := s.reconfigure(c); err != nil {
		return fmt.Errorf("initial configure failed: %s", err)
	}

	//poll torrents and files
	go func() {
		for {
			s.state.Lock()
			s.state.Torrents = s.engine.GetTorrents()
			s.state.Downloads = s.listFiles()
			// log.Printf("torrents #%d files #%d", len(s.state.Torrents), len(s.state.Downloads.Children))
			s.state.Unlock()
			s.state.Update()
			time.Sleep(1 * time.Second)
		}
	}()

	//ready
	return nil
}
예제 #2
0
func (s *Server) Run(version string) error {

	tls := s.CertPath != "" || s.KeyPath != "" //poor man's XOR
	if tls && (s.CertPath == "" || s.KeyPath == "") {
		return fmt.Errorf("You must provide both key and cert paths")
	}

	s.state.Stats.Title = s.Title
	s.state.Stats.Version = version
	s.state.Stats.Runtime = strings.TrimPrefix(runtime.Version(), "go")
	s.state.Stats.Uptime = time.Now()

	//init maps
	s.state.Users = map[string]*realtime.User{}
	//will use a the local embed/ dir if it exists, otherwise will use the hardcoded embedded binaries
	s.files = http.HandlerFunc(s.serveFiles)
	s.static = ctstatic.FileSystemHandler()
	s.scraper = &scraper.Handler{Log: false}
	if err := s.scraper.LoadConfig(defaultSearchConfig); err != nil {
		log.Fatal(err)
	}
	s.state.SearchProviders = s.scraper.Config //share scraper config
	s.scraperh = http.StripPrefix("/search", s.scraper)

	s.engine = engine.New()

	//realtime
	s.rt = realtime.NewHandler()
	if err := s.rt.Add("state", &s.state); err != nil {
		log.Fatalf("State object not syncable: %s", err)
	}
	//realtime user events
	go func() {
		for user := range s.rt.UserEvents() {
			if user.Connected {
				s.state.Users[user.ID] = user
			} else {
				delete(s.state.Users, user.ID)
			}
			s.state.Update()
		}
	}()

	//configure engine
	c := engine.Config{
		DownloadDirectory: "./downloads",
		EnableUpload:      true,
		AutoStart:         true,
	}
	if _, err := os.Stat(s.ConfigPath); err == nil {
		if b, err := ioutil.ReadFile(s.ConfigPath); err != nil {
			return fmt.Errorf("Read configuration error: %s", err)
		} else if len(b) == 0 {
			//ignore empty file
		} else if err := json.Unmarshal(b, &c); err != nil {
			return fmt.Errorf("Malformed configuration: %s", err)
		}
	}
	if c.IncomingPort <= 0 || c.IncomingPort >= 65535 {
		c.IncomingPort = 50007
	}
	if err := s.reconfigure(c); err != nil {
		return fmt.Errorf("initial configure failed: %s", err)
	}

	//poll torrents and files
	go func() {
		for {
			s.state.Lock()
			s.state.Torrents = s.engine.GetTorrents()
			s.state.Downloads = s.listFiles()
			// log.Printf("torrents #%d files #%d", len(s.state.Torrents), len(s.state.Downloads.Children))
			s.state.Unlock()
			s.state.Update()
			time.Sleep(1 * time.Second)
		}
	}()

	host := s.Host
	if host == "" {
		host = "0.0.0.0"
	}
	addr := fmt.Sprintf("%s:%d", host, s.Port)
	proto := "http"
	if tls {
		proto += "s"
	}
	log.Printf("Listening at %s://%s", proto, addr)

	if s.Open {
		openhost := host
		if openhost == "0.0.0.0" {
			openhost = "localhost"
		}
		go func() {
			time.Sleep(1 * time.Second)
			open.Run(fmt.Sprintf("%s://%s:%d", proto, openhost, s.Port))
		}()
	}

	h := http.Handler(http.HandlerFunc(s.handle))
	if s.Log {
		h = requestlog.Wrap(h)
	}

	if tls {
		return http.ListenAndServeTLS(addr, s.CertPath, s.KeyPath, h)
	} else {
		return http.ListenAndServe(addr, h)
	}
}