<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/oleksandr/bonjour"
)

const serviceName = "animation_server"

func main() {
	flag.Parse()
	if !*server && !*client {
		log.Println("must run either in server or client mode")
		os.Exit(1)
	}
	if *server && *client {
		log.Println("cannot run both in server and client mode")
		os.Exit(1)
	}
	s := &service{}
	if *server {
		log.Println("running server on port", *port)
		if len(*folder) == 0 {
			log.Println("must specify folder")
			os.Exit(1)
		}
		isThere, err := exists(*folder)
		if err != nil {
			log.Println(err)
			os.Exit(1)
		}
		if !isThere {
			log.Println("folder", *folder, "does not exist")
			os.Exit(1)
		}
		if err := s.register(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	if *client {
		log.Println("running client on port", *port)
		go func() {
			if err := s.browseUpdates(); err != nil {
				log.Println(err)
				os.Exit(1)
			}
		}()
		if err := s.proxyRequests(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	os.Exit(0)
}

func (s *service) handlerFunc(w http.ResponseWriter, r *http.Request) {
	resp, err := http.Get(fmt.Sprintf("http://%s:%d/gamestats.json", s.HostName, s.Port))
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With")
	w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS, PUT, POST, DELETE")
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Content-Type", "application/json")
	defer resp.Body.Close()
	_, err = w.Write(b)
	if err != nil {
		log.Println(err)
	}
}

func (s *service) proxyRequests() error {
	router := mux.NewRouter()
	router.HandleFunc("/gamestats.json", s.handlerFunc).Methods("GET", "OPTIONS")
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), context.ClearHandler(router))
}

// exists returns whether the given file or directory exists or not
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

var (
	server = flag.Bool("server", false, "serve data file over HTTP and advertise the service")
	folder = flag.String("folder", ".", "folder that includes gamestats.json")
	client = flag.Bool("client", false, "find where HTTP data is served and proxy it to localhost")
	port   = flag.Int("port", 8000, "port to listen on")
)
<commit_msg>dont error out if backend fetch fails<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"sync"
	"time"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/oleksandr/bonjour"
)

const serviceName = "animation_server"

func main() {
	flag.Parse()
	if !*server && !*client {
		log.Println("must run either in server or client mode")
		os.Exit(1)
	}
	if *server && *client {
		log.Println("cannot run both in server and client mode")
		os.Exit(1)
	}
	s := &service{}
	if *server {
		log.Println("running server on port", *port)
		if len(*folder) == 0 {
			log.Println("must specify folder")
			os.Exit(1)
		}
		isThere, err := exists(*folder)
		if err != nil {
			log.Println(err)
			os.Exit(1)
		}
		if !isThere {
			log.Println("folder", *folder, "does not exist")
			os.Exit(1)
		}
		if err := s.register(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	if *client {
		log.Println("running client on port", *port)
		go func() {
			if err := s.browseUpdates(); err != nil {
				log.Println(err)
				os.Exit(1)
			}
		}()
		if err := s.proxyRequests(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
	}
	os.Exit(0)
}

func (s *service) fetchData() ([]byte, error) {
	resp, err := http.Get(fmt.Sprintf("http://%s:%d/gamestats.json", s.HostName, s.Port))
	if err != nil {
		return nil, err
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	return b, nil
}

func (s *service) handlerFunc(w http.ResponseWriter, r *http.Request) {
	b, err := s.fetchData()
	if err != nil {
		log.Println(err)
	}
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With")
	w.Header().Add("Access-Control-Allow-Methods", "GET, OPTIONS, PUT, POST, DELETE")
	w.Header().Add("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Content-Type", "application/json")
	_, err = w.Write(b)
	if err != nil {
		log.Println(err)
	}
}

func (s *service) proxyRequests() error {
	router := mux.NewRouter()
	router.HandleFunc("/gamestats.json", s.handlerFunc).Methods("GET", "OPTIONS")
	return http.ListenAndServe(fmt.Sprintf(":%d", *port), context.ClearHandler(router))
}

// exists returns whether the given file or directory exists or not
func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

var (
	server = flag.Bool("server", false, "serve data file over HTTP and advertise the service")
	folder = flag.String("folder", ".", "folder that includes gamestats.json")
	client = flag.Bool("client", false, "find where HTTP data is served and proxy it to localhost")
	port   = flag.Int("port", 8000, "port to listen on")
)

{'fraction_non_alphanumeric': 0.17640807651434645, 'fraction_numerical': 0.0060219624512929506, 'mean_word_length': 3.721571906354515, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7348589', 'n_tokens_mistral': 2277, 'n_tokens_neox': 2141, 'n_words': 518}