<commit_before>package cloudfiles

import (
	"errors"
	"fmt"
	"github.com/OShalakhin/cloud/storage"
	"github.com/ncw/swift/rs"
	"net/url"
	"time"
)

type (
	// Storage is an implementation of Rackspace CloudFiles cloud storage
	Storage struct {
		Provider   storage.Provider
		Container  storage.Container
		Info       *Info
		Connection rs.RsConnection
	}
	// Info holds storage info
	Info struct {
		URL *url.URL
	}
)

// GetAuthURL gets auth URL based on storage provider AuthURL (ORD, DFW, HKG, LON, IAD, SYD)
func (s *Storage) GetAuthURL() string {
	switch {
	case s.Provider.AuthURL == "ORD" || s.Provider.AuthURL == "DFW" || s.Provider.AuthURL == "HKG" || s.Provider.AuthURL == "IAD" || s.Provider.AuthURL == "SYD":
		return authUS
	case s.Provider.AuthURL == "LON":
		return authLON
	default:
		return authUS
	}
}

// GetContainer from cloudfiles.Storage
func (s *Storage) GetContainer() (*storage.Container, error) {
	if s.Container.Name == "" || s.Container.Provider == "" {
		return nil, errors.New("empty container")
	}
	return &s.Container, nil
}

// Authenticate CloudFiles storage
func (s *Storage) Authenticate() error {
	s.Connection = rs.RsConnection{}
	s.Connection.UserName = s.Provider.Name
	s.Connection.ApiKey = s.Provider.Key
	s.Connection.AuthUrl = s.GetAuthURL()

	if err := s.Connection.Authenticate(); err != nil {
		panic(err)
	}
	// Set larger data timeout to reduce number of failed transfer
	s.Connection.Timeout = time.Duration(90) * time.Second
	// Set Info.URL empty as it must be initialized by GetURL
	s.Info.URL = new(url.URL)
	return nil
}

// Create file
func (s *Storage) Create(filename string, data []byte) error {
	// s.Authenticate()
	if err := s.Connection.ObjectPutBytes(s.Container.Name, filename, data, ""); err != nil {
		return fmt.Errorf(err.Error())
	}
	return nil
}

// Read file
func (s *Storage) Read(filename string) ([]byte, error) {
	data, err := s.Connection.ObjectGetBytes(s.Container.Name, filename)
	if err != nil {
		return []byte(""), err
	}
	return data, nil
}

// Update file
func (s *Storage) Update(filename string, data []byte) error {
	// delete
	if err := s.Delete(filename); err != nil {
		panic(err)
	}
	// create new
	return s.Create(filename, data)
}

// Upsert file
// func (s *Storage) Upsert(filename string, data []byte) error {
// 	return nil
// }

// Delete file
func (s *Storage) Delete(filename string) error {
	if err := s.Connection.ObjectDelete(s.Container.Name, filename); err != nil {
		return err
	}
	return nil
}

// GetURL returns url to the storage to use i.e. in templates
func (s *Storage) GetURL() *url.URL {
	if !s.Connection.Authenticated() {
		return new(url.URL)
	}

	u := s.Info.URL
	// generate it if not exist
	if u.RequestURI() == "/" {
		h, err := s.Connection.ContainerCDNMeta(s.Container.Name)
		if err != nil {
			panic(err)
		}
		u, err = u.Parse(h["X-Cdn-Ssl-Uri"])
		if err != nil {
			panic(err)
		}<commit_msg>raise panic(err) for GetURL() on auth and set Region based on Provider.AuthURL<commit_after>package cloudfiles

import (
	"errors"
	"fmt"
	"github.com/OShalakhin/cloud/storage"
	"github.com/ncw/swift/rs"
	"net/url"
	"time"
)

type (
	// Storage is an implementation of Rackspace CloudFiles cloud storage
	Storage struct {
		Provider   storage.Provider
		Container  storage.Container
		Info       *Info
		Connection rs.RsConnection
	}
	// Info holds storage info
	Info struct {
		URL *url.URL
	}
)

// GetAuthURL gets auth URL based on storage provider AuthURL (ORD, DFW, HKG, LON, IAD, SYD)
func (s *Storage) GetAuthURL() string {
	switch {
	case s.Provider.AuthURL == "ORD" || s.Provider.AuthURL == "DFW" || s.Provider.AuthURL == "HKG" || s.Provider.AuthURL == "IAD" || s.Provider.AuthURL == "SYD":
		return authUS
	case s.Provider.AuthURL == "LON":
		return authLON
	default:
		return authUS
	}
}

// GetContainer from cloudfiles.Storage
func (s *Storage) GetContainer() (*storage.Container, error) {
	if s.Container.Name == "" || s.Container.Provider == "" {
		return nil, errors.New("empty container")
	}
	return &s.Container, nil
}

// Authenticate CloudFiles storage
func (s *Storage) Authenticate() error {
	s.Connection = rs.RsConnection{}
	s.Connection.UserName = s.Provider.Name
	s.Connection.ApiKey = s.Provider.Key
	s.Connection.AuthUrl = s.GetAuthURL()
	s.Connection.Region = s.Provider.AuthURL

	if err := s.Connection.Authenticate(); err != nil {
		panic(err)
	}
	// Set larger data timeout to reduce number of failed transfer
	s.Connection.Timeout = time.Duration(90) * time.Second
	// Set Info.URL empty as it must be initialized by GetURL
	s.Info.URL = new(url.URL)
	return nil
}

// Create file
func (s *Storage) Create(filename string, data []byte) error {
	// s.Authenticate()
	if err := s.Connection.ObjectPutBytes(s.Container.Name, filename, data, ""); err != nil {
		return fmt.Errorf(err.Error())
	}
	return nil
}

// Read file
func (s *Storage) Read(filename string) ([]byte, error) {
	data, err := s.Connection.ObjectGetBytes(s.Container.Name, filename)
	if err != nil {
		return []byte(""), err
	}
	return data, nil
}

// Update file
func (s *Storage) Update(filename string, data []byte) error {
	// delete
	if err := s.Delete(filename); err != nil {
		panic(err)
	}
	// create new
	return s.Create(filename, data)
}

// Upsert file
// func (s *Storage) Upsert(filename string, data []byte) error {
// 	return nil
// }

// Delete file
func (s *Storage) Delete(filename string) error {
	if err := s.Connection.ObjectDelete(s.Container.Name, filename); err != nil {
		return err
	}
	return nil
}

// GetURL returns url to the storage to use i.e. in templates
func (s *Storage) GetURL() *url.URL {
	if !s.Connection.Authenticated() {
		err := s.Connection.Authenticate()
		if err != nil {
			panic(err)
		}
	}

	u := s.Info.URL
	// generate it if not exist
	if u.RequestURI() == "/" {
		h, err := s.Connection.ContainerCDNMeta(s.Container.Name)
		if err != nil {
			panic(err)
		}
		u, err = u.Parse(h["X-Cdn-Ssl-Uri"])
		if err != nil {
			panic(err)
		}
{'fraction_non_alphanumeric': 0.1460692871419054, 'fraction_numerical': 0.0006662225183211193, 'mean_word_length': 3.525244913338357, 'pattern_counts': {'":': 4, '<': 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': '1052342', 'n_tokens_mistral': 2152, 'n_tokens_neox': 2083, 'n_words': 589}