<commit_before>package plugins

import (
	"fmt"
	"log"

	"github.com/kolo/xmlrpc"
)

var (
	openSubtitlesSource = SubtitleSource{Name: "OpenSubtitles.org", Impl: openSubtitlesSearcher{}}
)

func init() {
	db := GetSubtitleDB()
	db.addSource(openSubtitlesSource)
}

type openSubtitlesSearcher struct{}

func (s openSubtitlesSearcher) GetSubtitle(file, language string) ([]SubtitleRef, error) {
	client, err := xmlrpc.NewClient("http://api.opensubtitles.org/xml-rpc", nil)
	if err != nil {
		return nil, err
	}

	loginRequest := []interface{}{"", "", "en", "OSTestUserAgent"}
	var loginResponse struct {
		Token   string  `xmlrpc:"token"`
		Status  string  `xmlrpc:"status"`
		Seconds float32 `xmlrpc:"seconds"`
	}

	err = client.Call("LogIn", loginRequest, &loginResponse)
	if err != nil {
		return nil, err
	}

	if loginResponse.Status != "200 OK" {
		return nil, fmt.Errorf("Bad rc from login call to opensubtitles: %s", loginResponse.Status)
	}

	hash, size, err := movieHashFile(file)
	if err != nil {
		return nil, err
	}

	searchRequest := []interface{}{
		loginResponse.Token,
		[]struct {
			MovieByteSize string `xmlrpc:"moviebytesize"`
			MovieHash     string `xmlrpc:"moviehash"`
			Language      string `xmlrpc:"sublanguageid"`
		}{{fmt.Sprintf("%d", size), hash, language}}}
	// SubFileName, SubHash, MovieNameEng, SubDownloadLink, SubtitlesLink
	var searchResponse struct {
		Status    string `xmlrpc:"status"`
		Subtitles []struct {
			FileName  string `xmlrpc:"SubFileName"`
			Hash      string `xmlrpc:"SubHash"`
			Format    string `xmlrpc:"SubFormat"`
			MovieName string `xmlrpc:"MovieName"`
			URL       string `xmlrpc:"SubDownloadLink"`
			Page      string `xmlrpc:"SubtitlesLink"`
		} `xmlrpc:"data"`
	}

	err = client.Call("SearchSubtitles", searchRequest, &searchResponse)
	if err != nil {
		return nil, err
	}

	var subs []SubtitleRef
	for _, sub := range searchResponse.Subtitles {
		subs = append(subs, SubtitleRef{
			FileName: sub.FileName,
			URL:      sub.URL,
			Source:   &openSubtitlesSource,
		})
	}

	err = client.Call("LogOut", loginResponse.Token, nil)
	if err != nil {
		log.Printf("LogOut from opensubtitles failed. Reason: %s\n", err)
	}

	return subs, nil
}<commit_msg>Refractored opensubtitles to separate functions<commit_after>package plugins

import (
	"fmt"
	"log"

	"github.com/kolo/xmlrpc"
)

var (
	openSubtitlesSource = SubtitleSource{Name: "OpenSubtitles.org", Impl: openSubtitlesSearcher{}}
)

func init() {
	db := GetSubtitleDB()
	db.addSource(openSubtitlesSource)
}

type openSubtitlesSearcher struct{}

func (s openSubtitlesSearcher) login(client *xmlrpc.Client, username, password, language, useragent string) (string, error) {
	request := []interface{}{username, password, language, useragent}
	var response struct {
		Token   string  `xmlrpc:"token"`
		Status  string  `xmlrpc:"status"`
		Seconds float32 `xmlrpc:"seconds"`
	}

	err := client.Call("LogIn", request, &response)
	if err != nil {
		return "", err
	}

	if response.Status != "200 OK" {
		return "", fmt.Errorf("Bad rc from login call to opensubtitles: %s", response.Status)
	}

	return response.Token, nil
}

func (s openSubtitlesSearcher) searchSubtitles(client *xmlrpc.Client, token, hash, language string, size int64) ([]SubtitleRef, error) {
	request := []interface{}{
		token,
		[]struct {
			MovieByteSize string `xmlrpc:"moviebytesize"`
			MovieHash     string `xmlrpc:"moviehash"`
			Language      string `xmlrpc:"sublanguageid"`
		}{{fmt.Sprintf("%d", size), hash, language}}}

	var response struct {
		Status    string `xmlrpc:"status"`
		Subtitles []struct {
			FileName  string `xmlrpc:"SubFileName"`
			Hash      string `xmlrpc:"SubHash"`
			Format    string `xmlrpc:"SubFormat"`
			MovieName string `xmlrpc:"MovieName"`
			URL       string `xmlrpc:"SubDownloadLink"`
			Page      string `xmlrpc:"SubtitlesLink"`
		} `xmlrpc:"data"`
	}

	err := client.Call("SearchSubtitles", request, &response)
	if err != nil {
		return nil, err
	}

	var subs []SubtitleRef
	for _, sub := range response.Subtitles {
		subs = append(subs, SubtitleRef{
			FileName: sub.FileName,
			URL:      sub.URL,
			Source:   &openSubtitlesSource,
		})
	}

	return subs, nil
}

func (s openSubtitlesSearcher) GetSubtitle(file, language string) ([]SubtitleRef, error) {
	client, err := xmlrpc.NewClient("http://api.opensubtitles.org/xml-rpc", nil)
	if err != nil {
		return nil, err
	}

	token, err := s.login(client, "", "", language, userAgent)
	if err != nil {
		return nil, err
	}

	hash, size, err := movieHashFile(file)
	if err != nil {
		return nil, err
	}

	subs, err := s.searchSubtitles(client, token, hash, language, size)

	err = client.Call("LogOut", token, nil)
	if err != nil {
		log.Printf("LogOut from opensubtitles failed. Reason: %s\n", err)
	}

	return subs, nil
}
{'fraction_non_alphanumeric': 0.13903966597077244, 'fraction_numerical': 0.0025052192066805845, 'mean_word_length': 4.2303493449781655, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 36}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6019240', 'n_tokens_mistral': 1740, 'n_tokens_neox': 1623, 'n_words': 409}