<commit_before>package server

import (
	"github.com/gin-gonic/contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/intervention-engine/fhir/auth"
	"github.com/mitre/heart"
	"golang.org/x/oauth2"
)

// RegisterController registers the CRUD routes (and middleware) for a FHIR resource
func RegisterController(name string, e *gin.Engine, m []gin.HandlerFunc, dal DataAccessLayer, config Config) {
	rc := NewResourceController(name, dal)
	rcBase := e.Group("/" + name)

	if len(m) > 0 {
		rcBase.Use(m...)
	}

	switch config.Auth.Method {
	case auth.AuthTypeNone:
		// do nothing
	case auth.AuthTypeOIDC:
		rcBase.Use(auth.HEARTScopesHandler(name))
	case auth.AuthTypeHEART:
		rcBase.Use(auth.HEARTScopesHandler(name))
	}

	rcBase.GET("", rc.IndexHandler)
	rcBase.POST("", rc.CreateHandler)
	rcBase.PUT("", rc.ConditionalUpdateHandler)
	rcBase.DELETE("", rc.ConditionalDeleteHandler)

	rcItem := rcBase.Group("/:id")
	rcItem.GET("", rc.ShowHandler)
	rcItem.PUT("", rc.UpdateHandler)
	rcItem.DELETE("", rc.DeleteHandler)
}

// RegisterRoutes registers the routes for each of the FHIR resources
func RegisterRoutes(e *gin.Engine, config map[string][]gin.HandlerFunc, dal DataAccessLayer, serverConfig Config) {

	switch serverConfig.Auth.Method {
	case auth.AuthTypeNone:
		// do nothing
	case auth.AuthTypeOIDC:
		// Set up sessions so we can keep track of the logged in user
		store := sessions.NewCookieStore([]byte(serverConfig.Auth.SessionSecret))
		e.Use(sessions.Sessions("mysession", store))
		// The OIDCAuthenticationHandler is set up before the IndexHandler in the handler function
		// chain. It will check to see if the user is logged in based on their session. If they are not
		// the user will be redirected to the authentication endpoint at the OP.
		oauthConfig := oauth2.Config{ClientID: serverConfig.Auth.ClientID,
			ClientSecret: serverConfig.Auth.ClientSecret,
			Endpoint: oauth2.Endpoint{AuthURL: serverConfig.Auth.AuthorizationURL,
				TokenURL: serverConfig.Auth.TokenURL},
		}
		oidcHandler := auth.OIDCAuthenticationHandler(oauthConfig)
		oauthHandler := auth.OAuthIntrospectionHandler(serverConfig.Auth.ClientID,
			serverConfig.Auth.ClientSecret, serverConfig.Auth.IntrospectionURL)
		e.Use(func(c *gin.Context) {
			if c.Request.Header.Get("Authorization") != "" {
				oauthHandler(c)
			} else {
				oidcHandler(c)
			}
		})
		// This handler is to take the redirect from the OP when the user logs in. It will
		// then fetch information about the user by hitting the user info endpoint and put
		// that in the session. Lastly, this handler is set up to redirect the user back
		// to the root.
		e.GET("/redirect", auth.RedirectHandler(oauthConfig, serverConfig.ServerURL,
			serverConfig.Auth.UserInfoURL))
		e.GET("/logout", heart.LogoutHandler)

	case auth.AuthTypeHEART:
		heart.SetUpRoutes(serverConfig.Auth.JWKPath, serverConfig.Auth.ClientID, serverConfig.Auth.OPURL,
			serverConfig.ServerURL, serverConfig.Auth.SessionSecret, e)

	}

	// Batch Support
	batch := NewBatchController(dal)
	batchHandlers := make([]gin.HandlerFunc, len(config["Batch"]))
	copy(batchHandlers, config["Batch"])
	batchHandlers = append(batchHandlers, batch.Post)
	e.POST("/", batchHandlers...)

	// Resources

	RegisterController("Appointment", e, config["Appointment"], dal, serverConfig)
	RegisterController("ReferralRequest", e, config["ReferralRequest"], dal, serverConfig)
	RegisterController("Account", e, config["Account"], dal, serverConfig)
	RegisterController("Provenance", e, config["Provenance"], dal, serverConfig)
	RegisterController("Questionnaire", e, config["Questionnaire"], dal, serverConfig)
	RegisterController("ExplanationOfBenefit", e, config["ExplanationOfBenefit"], dal, serverConfig)
	RegisterController("DocumentManifest", e, config["DocumentManifest"], dal, serverConfig)
	RegisterController("Specimen", e, config["Specimen"], dal, serverConfig)
	RegisterController("AllergyIntolerance", e, config["AllergyIntolerance"], dal, serverConfig)
	RegisterController("CarePlan", e, config["CarePlan"], dal, serverConfig)
	RegisterController("Goal", e, config["Goal"], dal, serverConfig)
	RegisterController("StructureDefinition", e, config["StructureDefinition"], dal, serverConfig)
	RegisterController("EnrollmentRequest", e, config["EnrollmentRequest"], dal, serverConfig)
	RegisterController("EpisodeOfCare", e, config["EpisodeOfCare"], dal, serverConfig)
	RegisterController("OperationOutcome", e, config["OperationOutcome"], dal, serverConfig)
	RegisterController("Medication", e, config["Medication"], dal, serverConfig)
	RegisterController("Procedure", e, config["Procedure"], dal, serverConfig)
	RegisterController("List", e, config["List"], dal, serverConfig)
	RegisterController("ConceptMap", e, config["ConceptMap"], dal, serverConfig)
	RegisterController("Subscription", e, config["Subscription"], dal, serverConfig)
	RegisterController("ValueSet", e, config["ValueSet"], dal, serverConfig)
	RegisterController("OperationDefinition", e, config["OperationDefinition"], dal, serverConfig)
	RegisterController("DocumentReference", e, config["DocumentReference"], dal, serverConfig)
	RegisterController("Order", e, config["Order"], dal, serverConfig)
	RegisterController("Immunization", e, config["Immunization"], dal, serverConfig)
	RegisterController("Device", e, config["Device"], dal, serverConfig)
	RegisterController("VisionPrescription", e, config["VisionPrescription"], dal, serverConfig)
	RegisterController("Media", e, config["Media"], dal, serverConfig)
	RegisterController("Conformance", e, config["Conformance"], dal, serverConfig)
	RegisterController("ProcedureRequest", e, config["ProcedureRequest"], dal, serverConfig)
	RegisterController("EligibilityResponse", e, config["EligibilityResponse"], dal, serverConfig)
	RegisterController("DeviceUseRequest", e, config["DeviceUseRequest"], dal, serverConfig)
	RegisterController("DeviceMetric", e, config["DeviceMetric"], dal, serverConfig)
	RegisterController("Flag", e, config["Flag"], dal, serverConfig)
	RegisterController("RelatedPerson", e, config["RelatedPerson"], dal, serverConfig)
	RegisterController("SupplyRequest", e, config["SupplyRequest"], dal, serverConfig)
	RegisterController("Practitioner", e, config["Practitioner"], dal, serverConfig)
	RegisterController("AppointmentResponse", e, config["AppointmentResponse"], dal, serverConfig)
	RegisterController("Observation", e, config["Observation"], dal, serverConfig)
	RegisterController("MedicationAdministration", e, config["MedicationAdministration"], dal, serverConfig)
	RegisterController("Slot", e, config["Slot"], dal, serverConfig)
	RegisterController("EnrollmentResponse", e, config["EnrollmentResponse"], dal, serverConfig)
	RegisterController("Binary", e, config["Binary"], dal, serverConfig)
	RegisterController("MedicationStatement", e, config["MedicationStatement"], dal, serverConfig)
	RegisterController("Person", e, config["Person"], dal, serverConfig)
	RegisterController("Contract", e, config["Contract"], dal, serverConfig)
	RegisterController("CommunicationRequest", e, config["CommunicationRequest"], dal, serverConfig)
	RegisterController("RiskAssessment", e, config["RiskAssessment"], dal, serverConfig)
	RegisterController("TestScript", e, config["TestScript"], dal, serverConfig)
	RegisterController("Basic", e, config["Basic"], dal, serverConfig)
	RegisterController("Group", e, config["Group"], dal, serverConfig)
	RegisterController("PaymentNotice", e, config["PaymentNotice"], dal, serverConfig)
	RegisterController("Organization", e, config["Organization"], dal, serverConfig)
	RegisterController("ImplementationGuide", e, config["ImplementationGuide"], dal, serverConfig)
	RegisterController("ClaimResponse", e, config["ClaimResponse"], dal, serverConfig)
	RegisterController("EligibilityRequest", e, config["EligibilityRequest"], dal, serverConfig)
	RegisterController("ProcessRequest", e, config["ProcessRequest"], dal, serverConfig)
	RegisterController("MedicationDispense", e, config["MedicationDispense"], dal, serverConfig)
	RegisterController("DiagnosticReport", e, config["DiagnosticReport"], dal, serverConfig)
	RegisterController("ImagingStudy", e, config["ImagingStudy"], dal, serverConfig)
	RegisterController("ImagingObjectSelection", e, config["ImagingObjectSelection"], dal, serverConfig)
	RegisterController("HealthcareService", e, config["HealthcareService"], dal, serverConfig)
	RegisterController("DataElement", e, config["DataElement"], dal, serverConfig)
	RegisterController("DeviceComponent", e, config["DeviceComponent"], dal, serverConfig)
	RegisterController("FamilyMemberHistory", e, config["FamilyMemberHistory"], dal, serverConfig)
	RegisterController("NutritionOrder", e, config["NutritionOrder"], dal, serverConfig)
	RegisterController("Encounter", e, config["Encounter"], dal, serverConfig)
	RegisterController("Substance", e, config["Substance"], dal, serverConfig)
	RegisterController("AuditEvent", e, config["AuditEvent"], dal, serverConfig)
	RegisterController("MedicationOrder", e, config["MedicationOrder"], dal, serverConfig)
	RegisterController("SearchParameter", e, config["SearchParameter"], dal, serverConfig)
	RegisterController("PaymentReconciliation", e, config["PaymentReconciliation"], dal, serverConfig)
	RegisterController("Communication", e, config["Communication"], dal, serverConfig)
	RegisterController("Condition", e, config["Condition"], dal, serverConfig)
	RegisterController("Composition", e, config["Composition"], dal, serverConfig)
	RegisterController("DetectedIssue", e, config["DetectedIssue"], dal, serverConfig)
	RegisterController("Bundle", e, config["Bundle"], dal, serverConfig)
	RegisterController("DiagnosticOrder", e, config["DiagnosticOrder"], dal, serverConfig)
	RegisterController("Patient", e, config["Patient"], dal, serverConfig)
	RegisterController("OrderResponse", e, config["OrderResponse"], dal, serverConfig)
	RegisterController("Coverage", e, config["Coverage"], dal, serverConfig)
	RegisterController("QuestionnaireResponse", e, config["QuestionnaireResponse"], dal, serverConfig)
	RegisterController("DeviceUseStatement", e, config["DeviceUseStatement"], dal, serverConfig)
	RegisterController("ProcessResponse", e, config["ProcessResponse"], dal, serverConfig)
	RegisterController("NamingSystem", e, config["NamingSystem"], dal, serverConfig)
	RegisterController("Schedule", e, config["Schedule"], dal, serverConfig)
	RegisterController("SupplyDelivery", e, config["SupplyDelivery"], dal, serverConfig)
	RegisterController("ClinicalImpression", e, config["ClinicalImpression"], dal, serverConfig)
	RegisterController("MessageHeader", e, config["MessageHeader"], dal, serverConfig)
	RegisterController("Claim", e, config["Claim"], dal, serverConfig)
	RegisterController("ImmunizationRecommendation", e, config["ImmunizationRecommendation"], dal, serverConfig)
	RegisterController("Location", e, config["Location"], dal, serverConfig)
	RegisterController("BodySite", e, config["BodySite"], dal, serverConfig)
}
<commit_msg>Updated routing.go after code generation refactor<commit_after>package server

// This file is generated by the FHIR golang generator.  This file should not be manually modified.

import (
	"github.com/gin-gonic/contrib/sessions"
	"github.com/gin-gonic/gin"
	"github.com/intervention-engine/fhir/auth"
	"github.com/mitre/heart"
	"golang.org/x/oauth2"
)

// RegisterController registers the CRUD routes (and middleware) for a FHIR resource
func RegisterController(name string, e *gin.Engine, m []gin.HandlerFunc, dal DataAccessLayer, config Config) {
	rc := NewResourceController(name, dal)
	rcBase := e.Group("/" + name)

	if len(m) > 0 {
		rcBase.Use(m...)
	}

	switch config.Auth.Method {
	case auth.AuthTypeNone:
		// do nothing
	case auth.AuthTypeOIDC:
		rcBase.Use(auth.HEARTScopesHandler(name))
	case auth.AuthTypeHEART:
		rcBase.Use(auth.HEARTScopesHandler(name))
	}

	rcBase.GET("", rc.IndexHandler)
	rcBase.POST("", rc.CreateHandler)
	rcBase.PUT("", rc.ConditionalUpdateHandler)
	rcBase.DELETE("", rc.ConditionalDeleteHandler)

	rcItem := rcBase.Group("/:id")
	rcItem.GET("", rc.ShowHandler)
	rcItem.PUT("", rc.UpdateHandler)
	rcItem.DELETE("", rc.DeleteHandler)
}

// RegisterRoutes registers the routes for each of the FHIR resources
func RegisterRoutes(e *gin.Engine, config map[string][]gin.HandlerFunc, dal DataAccessLayer, serverConfig Config) {

	switch serverConfig.Auth.Method {
	case auth.AuthTypeNone:
		// do nothing
	case auth.AuthTypeOIDC:
		// Set up sessions so we can keep track of the logged in user
		store := sessions.NewCookieStore([]byte(serverConfig.Auth.SessionSecret))
		e.Use(sessions.Sessions("mysession", store))
		// The OIDCAuthenticationHandler is set up before the IndexHandler in the handler function
		// chain. It will check to see if the user is logged in based on their session. If they are not
		// the user will be redirected to the authentication endpoint at the OP.
		oauthConfig := oauth2.Config{ClientID: serverConfig.Auth.ClientID,
			ClientSecret: serverConfig.Auth.ClientSecret,
			Endpoint: oauth2.Endpoint{AuthURL: serverConfig.Auth.AuthorizationURL,
				TokenURL: serverConfig.Auth.TokenURL},
		}
		oidcHandler := auth.OIDCAuthenticationHandler(oauthConfig)
		oauthHandler := auth.OAuthIntrospectionHandler(serverConfig.Auth.ClientID,
			serverConfig.Auth.ClientSecret, serverConfig.Auth.IntrospectionURL)
		e.Use(func(c *gin.Context) {
			if c.Request.Header.Get("Authorization") != "" {
				oauthHandler(c)
			} else {
				oidcHandler(c)
			}
		})
		// This handler is to take the redirect from the OP when the user logs in. It will
		// then fetch information about the user by hitting the user info endpoint and put
		// that in the session. Lastly, this handler is set up to redirect the user back
		// to the root.
		e.GET("/redirect", auth.RedirectHandler(oauthConfig, serverConfig.ServerURL,
			serverConfig.Auth.UserInfoURL))
		e.GET("/logout", heart.LogoutHandler)

	case auth.AuthTypeHEART:
		heart.SetUpRoutes(serverConfig.Auth.JWKPath, serverConfig.Auth.ClientID, serverConfig.Auth.OPURL,
			serverConfig.ServerURL, serverConfig.Auth.SessionSecret, e)

	}

	// Batch Support
	batch := NewBatchController(dal)
	batchHandlers := make([]gin.HandlerFunc, len(config["Batch"]))
	copy(batchHandlers, config["Batch"])
	batchHandlers = append(batchHandlers, batch.Post)
	e.POST("/", batchHandlers...)

	// Resources

	RegisterController("Account", e, config["Account"], dal, serverConfig)
	RegisterController("AllergyIntolerance", e, config["AllergyIntolerance"], dal, serverConfig)
	RegisterController("Appointment", e, config["Appointment"], dal, serverConfig)
	RegisterController("AppointmentResponse", e, config["AppointmentResponse"], dal, serverConfig)
	RegisterController("AuditEvent", e, config["AuditEvent"], dal, serverConfig)
	RegisterController("Basic", e, config["Basic"], dal, serverConfig)
	RegisterController("Binary", e, config["Binary"], dal, serverConfig)
	RegisterController("BodySite", e, config["BodySite"], dal, serverConfig)
	RegisterController("Bundle", e, config["Bundle"], dal, serverConfig)
	RegisterController("CarePlan", e, config["CarePlan"], dal, serverConfig)
	RegisterController("Claim", e, config["Claim"], dal, serverConfig)
	RegisterController("ClaimResponse", e, config["ClaimResponse"], dal, serverConfig)
	RegisterController("ClinicalImpression", e, config["ClinicalImpression"], dal, serverConfig)
	RegisterController("Communication", e, config["Communication"], dal, serverConfig)
	RegisterController("CommunicationRequest", e, config["CommunicationRequest"], dal, serverConfig)
	RegisterController("Composition", e, config["Composition"], dal, serverConfig)
	RegisterController("ConceptMap", e, config["ConceptMap"], dal, serverConfig)
	RegisterController("Condition", e, config["Condition"], dal, serverConfig)
	RegisterController("Conformance", e, config["Conformance"], dal, serverConfig)
	RegisterController("Contract", e, config["Contract"], dal, serverConfig)
	RegisterController("Coverage", e, config["Coverage"], dal, serverConfig)
	RegisterController("DataElement", e, config["DataElement"], dal, serverConfig)
	RegisterController("DetectedIssue", e, config["DetectedIssue"], dal, serverConfig)
	RegisterController("Device", e, config["Device"], dal, serverConfig)
	RegisterController("DeviceComponent", e, config["DeviceComponent"], dal, serverConfig)
	RegisterController("DeviceMetric", e, config["DeviceMetric"], dal, serverConfig)
	RegisterController("DeviceUseRequest", e, config["DeviceUseRequest"], dal, serverConfig)
	RegisterController("DeviceUseStatement", e, config["DeviceUseStatement"], dal, serverConfig)
	RegisterController("DiagnosticOrder", e, config["DiagnosticOrder"], dal, serverConfig)
	RegisterController("DiagnosticReport", e, config["DiagnosticReport"], dal, serverConfig)
	RegisterController("DocumentManifest", e, config["DocumentManifest"], dal, serverConfig)
	RegisterController("DocumentReference", e, config["DocumentReference"], dal, serverConfig)
	RegisterController("EligibilityRequest", e, config["EligibilityRequest"], dal, serverConfig)
	RegisterController("EligibilityResponse", e, config["EligibilityResponse"], dal, serverConfig)
	RegisterController("Encounter", e, config["Encounter"], dal, serverConfig)
	RegisterController("EnrollmentRequest", e, config["EnrollmentRequest"], dal, serverConfig)
	RegisterController("EnrollmentResponse", e, config["EnrollmentResponse"], dal, serverConfig)
	RegisterController("EpisodeOfCare", e, config["EpisodeOfCare"], dal, serverConfig)
	RegisterController("ExplanationOfBenefit", e, config["ExplanationOfBenefit"], dal, serverConfig)
	RegisterController("FamilyMemberHistory", e, config["FamilyMemberHistory"], dal, serverConfig)
	RegisterController("Flag", e, config["Flag"], dal, serverConfig)
	RegisterController("Goal", e, config["Goal"], dal, serverConfig)
	RegisterController("Group", e, config["Group"], dal, serverConfig)
	RegisterController("HealthcareService", e, config["HealthcareService"], dal, serverConfig)
	RegisterController("ImagingObjectSelection", e, config["ImagingObjectSelection"], dal, serverConfig)
	RegisterController("ImagingStudy", e, config["ImagingStudy"], dal, serverConfig)
	RegisterController("Immunization", e, config["Immunization"], dal, serverConfig)
	RegisterController("ImmunizationRecommendation", e, config["ImmunizationRecommendation"], dal, serverConfig)
	RegisterController("ImplementationGuide", e, config["ImplementationGuide"], dal, serverConfig)
	RegisterController("List", e, config["List"], dal, serverConfig)
	RegisterController("Location", e, config["Location"], dal, serverConfig)
	RegisterController("Media", e, config["Media"], dal, serverConfig)
	RegisterController("Medication", e, config["Medication"], dal, serverConfig)
	RegisterController("MedicationAdministration", e, config["MedicationAdministration"], dal, serverConfig)
	RegisterController("MedicationDispense", e, config["MedicationDispense"], dal, serverConfig)
	RegisterController("MedicationOrder", e, config["MedicationOrder"], dal, serverConfig)
	RegisterController("MedicationStatement", e, config["MedicationStatement"], dal, serverConfig)
	RegisterController("MessageHeader", e, config["MessageHeader"], dal, serverConfig)
	RegisterController("NamingSystem", e, config["NamingSystem"], dal, serverConfig)
	RegisterController("NutritionOrder", e, config["NutritionOrder"], dal, serverConfig)
	RegisterController("Observation", e, config["Observation"], dal, serverConfig)
	RegisterController("OperationDefinition", e, config["OperationDefinition"], dal, serverConfig)
	RegisterController("OperationOutcome", e, config["OperationOutcome"], dal, serverConfig)
	RegisterController("Order", e, config["Order"], dal, serverConfig)
	RegisterController("OrderResponse", e, config["OrderResponse"], dal, serverConfig)
	RegisterController("Organization", e, config["Organization"], dal, serverConfig)
	RegisterController("Patient", e, config["Patient"], dal, serverConfig)
	RegisterController("PaymentNotice", e, config["PaymentNotice"], dal, serverConfig)
	RegisterController("PaymentReconciliation", e, config["PaymentReconciliation"], dal, serverConfig)
	RegisterController("Person", e, config["Person"], dal, serverConfig)
	RegisterController("Practitioner", e, config["Practitioner"], dal, serverConfig)
	RegisterController("Procedure", e, config["Procedure"], dal, serverConfig)
	RegisterController("ProcedureRequest", e, config["ProcedureRequest"], dal, serverConfig)
	RegisterController("ProcessRequest", e, config["ProcessRequest"], dal, serverConfig)
	RegisterController("ProcessResponse", e, config["ProcessResponse"], dal, serverConfig)
	RegisterController("Provenance", e, config["Provenance"], dal, serverConfig)
	RegisterController("Questionnaire", e, config["Questionnaire"], dal, serverConfig)
	RegisterController("QuestionnaireResponse", e, config["QuestionnaireResponse"], dal, serverConfig)
	RegisterController("ReferralRequest", e, config["ReferralRequest"], dal, serverConfig)
	RegisterController("RelatedPerson", e, config["RelatedPerson"], dal, serverConfig)
	RegisterController("RiskAssessment", e, config["RiskAssessment"], dal, serverConfig)
	RegisterController("Schedule", e, config["Schedule"], dal, serverConfig)
	RegisterController("SearchParameter", e, config["SearchParameter"], dal, serverConfig)
	RegisterController("Slot", e, config["Slot"], dal, serverConfig)
	RegisterController("Specimen", e, config["Specimen"], dal, serverConfig)
	RegisterController("StructureDefinition", e, config["StructureDefinition"], dal, serverConfig)
	RegisterController("Subscription", e, config["Subscription"], dal, serverConfig)
	RegisterController("Substance", e, config["Substance"], dal, serverConfig)
	RegisterController("SupplyDelivery", e, config["SupplyDelivery"], dal, serverConfig)
	RegisterController("SupplyRequest", e, config["SupplyRequest"], dal, serverConfig)
	RegisterController("TestScript", e, config["TestScript"], dal, serverConfig)
	RegisterController("ValueSet", e, config["ValueSet"], dal, serverConfig)
	RegisterController("VisionPrescription", e, config["VisionPrescription"], dal, serverConfig)

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"sort"
	"time"

	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"

	"github.com/aerogo/http/client"
	"github.com/animenotifier/arn"
	"github.com/fatih/color"
)

func main() {
	color.Yellow("Updating anime ratings")

	defer color.Green("Finished.")
	defer arn.Node.Close()

	characters := arn.FilterCharacters(func(character *arn.Character) bool {
		return character.Image.LastModified == 0
	})

	sort.Slice(characters, func(i, j int) bool {
		return characters[i].ID < characters[j].ID
	})

	for index, character := range characters {
		fmt.Printf("[%d / %d] %s %s\n", index+1, len(characters), character.ID, color.CyanString(character.String()))
		download(character.ID)
	}

	time.Sleep(time.Second)
}

func download(characterID string) {
	character, err := arn.GetCharacter(characterID)

	if err != nil {
		color.Red(err.Error())
		return
	}

	url := fmt.Sprintf("https://media.kitsu.io/characters/images/%s/original%s", character.GetMapping("kitsu/character"), character.Image.Extension)
	response, err := client.Get(url).End()

	if err != nil {
		color.Red(err.Error())
		return
	}

	err = character.SetImageBytes(response.Bytes())

	if err != nil {
		color.Red(err.Error())
		return
	}

	character.Save()
}
<commit_msg>Added status code check<commit_after>package main

import (
	"fmt"
	"net/http"
	"sort"
	"time"

	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"

	"github.com/aerogo/http/client"
	"github.com/animenotifier/arn"
	"github.com/fatih/color"
)

func main() {
	color.Yellow("Updating anime ratings")

	defer color.Green("Finished.")
	defer arn.Node.Close()

	characters := arn.FilterCharacters(func(character *arn.Character) bool {
		return character.Image.LastModified == 0
	})

	sort.Slice(characters, func(i, j int) bool {
		return characters[i].ID < characters[j].ID
	})

	for index, character := range characters {
		fmt.Printf("[%d / %d] %s %s\n", index+1, len(characters), character.ID, color.CyanString(character.String()))
		download(character.ID)
	}

	time.Sleep(time.Second)
}

func download(characterID string) {
	character, err := arn.GetCharacter(characterID)

	if err != nil {
		color.Red(err.Error())
		return
	}

	url := fmt.Sprintf("https://media.kitsu.io/characters/images/%s/original%s", character.GetMapping("kitsu/character"), character.Image.Extension)
	response, err := client.Get(url).End()

	if err != nil {
		color.Red(err.Error())
		return
	}

	if response.StatusCode() != http.StatusOK {
		color.Red("Status: %d", response.StatusCode())
		return
	}

	err = character.SetImageBytes(response.Bytes())

	if err != nil {
		color.Red(err.Error())
		return
	}

	character.Save()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"net/http"
	"time"

	"github.com/icco/xsrftoken"
	"github.com/pilu/traffic"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"
)

type NewPostPageData struct {
	IsAdmin   bool
	LogoutUrl string
	User      string
	Xsrf      string
	Links     linkDays
}

func NewPostGetHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	u := user.Current(c)
	if u == nil {
		url, _ := user.LoginURL(c, "/post/new")
		http.Redirect(w, r.Request, url, 302)
		return
	} else {
		log.Infof(c, "Logged in as: %s", u.String())
	}

	if u != nil && !user.IsAdmin(c) {
		http.Error(w, errors.New("Not a valid user.").Error(), 403)
		return
	} else {
		url, _ := user.LogoutURL(c, "/")
		token := xsrftoken.Generate(GetFlagLogError(c, "SESSION_KEY"), u.String(), "/post/new")
		links, err := LinksByDay(c, 15)
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}

		responseData := &NewPostPageData{
			LogoutUrl: url,
			User:      u.String(),
			Xsrf:      token,
			IsAdmin:   user.IsAdmin(c),
			Links:     *links,
		}
		w.Render("new_post", responseData)
	}
}

func NewPostPostHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	u := user.Current(c)
	if u == nil {
		url, _ := user.LoginURL(c, "/post/new")
		http.Redirect(w, r.Request, url, 302)
		return
	} else {
		log.Infof(c, "Logged in as: %s", u.String())
	}

	if u != nil && !user.IsAdmin(c) {
		http.Error(w, errors.New("Not a valid user.").Error(), 403)
		return
	} else {
		err := r.ParseForm()
		if err != nil {
			log.Warningf(c, "Couldn't parse form: %v", r)
		}
		title := r.Request.FormValue("title")
		content := r.Request.FormValue("text")
		xsrf := r.Request.FormValue("xsrf")
		tags, err := ParseTags(content)
		draft := r.Request.FormValue("draft") == "on"
		if err != nil {
			log.Warningf(c, "Couldn't parse tags: %v", err)
			tags = []string{}
		}

		log.Infof(c, "Got POST params: title: %+v, text: %+v, xsrf: %v, draft: %v", title, content, xsrf, draft)

		if xsrftoken.Valid(xsrf, GetFlagLogError(c, "SESSION_KEY"), u.String(), "/post/new") {
			log.Infof(c, "Valid Token!")
		} else {
			log.Infof(c, "Invalid Token...")
			http.Error(w, errors.New("Invalid Token").Error(), 403)
			return
		}

		e := NewEntry(title, content, time.Now(), tags)
		e.Draft = draft
		err = e.Save(c)
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}

		http.Redirect(w, r.Request, e.Url(), 302)
		return
	}
}
<commit_msg>12 instead of 15<commit_after>package main

import (
	"errors"
	"net/http"
	"time"

	"github.com/icco/xsrftoken"
	"github.com/pilu/traffic"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"google.golang.org/appengine/user"
)

type NewPostPageData struct {
	IsAdmin   bool
	LogoutUrl string
	User      string
	Xsrf      string
	Links     linkDays
}

func NewPostGetHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	u := user.Current(c)
	if u == nil {
		url, _ := user.LoginURL(c, "/post/new")
		http.Redirect(w, r.Request, url, 302)
		return
	} else {
		log.Infof(c, "Logged in as: %s", u.String())
	}

	if u != nil && !user.IsAdmin(c) {
		http.Error(w, errors.New("Not a valid user.").Error(), 403)
		return
	} else {
		url, _ := user.LogoutURL(c, "/")
		token := xsrftoken.Generate(GetFlagLogError(c, "SESSION_KEY"), u.String(), "/post/new")
		links, err := LinksByDay(c, 12)
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}

		responseData := &NewPostPageData{
			LogoutUrl: url,
			User:      u.String(),
			Xsrf:      token,
			IsAdmin:   user.IsAdmin(c),
			Links:     *links,
		}
		w.Render("new_post", responseData)
	}
}

func NewPostPostHandler(w traffic.ResponseWriter, r *traffic.Request) {
	c := appengine.NewContext(r.Request)
	u := user.Current(c)
	if u == nil {
		url, _ := user.LoginURL(c, "/post/new")
		http.Redirect(w, r.Request, url, 302)
		return
	} else {
		log.Infof(c, "Logged in as: %s", u.String())
	}

	if u != nil && !user.IsAdmin(c) {
		http.Error(w, errors.New("Not a valid user.").Error(), 403)
		return
	} else {
		err := r.ParseForm()
		if err != nil {
			log.Warningf(c, "Couldn't parse form: %v", r)
		}
		title := r.Request.FormValue("title")
		content := r.Request.FormValue("text")
		xsrf := r.Request.FormValue("xsrf")
		tags, err := ParseTags(content)
		draft := r.Request.FormValue("draft") == "on"
		if err != nil {
			log.Warningf(c, "Couldn't parse tags: %v", err)
			tags = []string{}
		}

		log.Infof(c, "Got POST params: title: %+v, text: %+v, xsrf: %v, draft: %v", title, content, xsrf, draft)

		if xsrftoken.Valid(xsrf, GetFlagLogError(c, "SESSION_KEY"), u.String(), "/post/new") {
			log.Infof(c, "Valid Token!")
		} else {
			log.Infof(c, "Invalid Token...")
			http.Error(w, errors.New("Invalid Token").Error(), 403)
			return
		}

		e := NewEntry(title, content, time.Now(), tags)
		e.Draft = draft
		err = e.Save(c)
		if err != nil {
			http.Error(w, err.Error(), 500)
			return
		}

		http.Redirect(w, r.Request, e.Url(), 302)
		return
	}
}
<|endoftext|>


<commit_before>package modpm

import (
    "fmt"
    "golang.org/x/net/html"
    "net/http"
    "github.com/davidscholberg/irkbot/lib"
    "github.com/mvdan/xurls"
)

// Url attempts to fetch the title of the HTML document returned by a URL
func Url(p *lib.Privmsg) bool {
    urls := xurls.Strict.FindAllString(p.Msg, -1)

    for _, url := range urls {
        title, err := getHtmlTitle(url)
        if err != nil {
            continue
        }
        lib.Say(p, fmt.Sprintf("^ %s - [%s]", title, url))
    }

    // don't consume the message, in case there are commands in it
    return false
}

// getHtmlTitle returns the HTML title found at the given URL.
func getHtmlTitle(url string) (string, error) {
    response, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer response.Body.Close()

    doctree, err := html.Parse(response.Body)
    if err != nil {
        return "", err
    }

    title, err := searchForHtmlTitle(doctree)
    if err != nil {
        return "", err
    }
    if len(title) == 0 {
        return "", fmt.Errorf("title not found")
    }

    return title, nil
}

// searchForHtmlTitle searches the parsed html document for the title.
func searchForHtmlTitle(n *html.Node) (string, error) {
    if n.Type == html.ElementNode && n.Data == "title" {
        if n.FirstChild.Type != html.TextNode {
            err := fmt.Errorf("child of title not TextNode type")
            return "", err
        }
        return n.FirstChild.Data, nil
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        title, err := searchForHtmlTitle(c)
        if len(title) > 0 || err != nil {
            return title, err
        }
    }
    return "", nil
}
<commit_msg>url: added basic URL validation to prevent localhost and private network probing<commit_after>package modpm

import (
    "fmt"
    "golang.org/x/net/html"
    "net/http"
    "strings"
    urllib "net/url"
    "github.com/davidscholberg/irkbot/lib"
    "github.com/mvdan/xurls"
)

// Url attempts to fetch the title of the HTML document returned by a URL
func Url(p *lib.Privmsg) bool {
    urls := xurls.Strict.FindAllString(p.Msg, -1)

    for _, url := range urls {
        if v, _ := validateUrl(url); !v {
            lib.Say(p, fmt.Sprintf("%s: :|", p.Event.Nick))
            return false
        }
        title, err := getHtmlTitle(url)
        if err != nil {
            continue
        }
        lib.Say(p, fmt.Sprintf("^ %s - [%s]", title, url))
    }

    // don't consume the message, in case there are commands in it
    return false
}

// getHtmlTitle returns the HTML title found at the given URL.
func getHtmlTitle(url string) (string, error) {
    response, err := http.Get(url)
    if err != nil {
        return "", err
    }
    defer response.Body.Close()

    doctree, err := html.Parse(response.Body)
    if err != nil {
        return "", err
    }

    title, err := searchForHtmlTitle(doctree)
    if err != nil {
        return "", err
    }
    if len(title) == 0 {
        return "", fmt.Errorf("title not found")
    }

    return title, nil
}

// validateUrl ensures that the given URL is safe to GET.
func validateUrl(urlStr string) (bool, error) {
    url, err := urllib.Parse(urlStr)
    if err != nil {
        return false, err
    }

    // TODO: add CIDR matching
    if strings.HasPrefix(url.Host, "127.") ||
        strings.HasPrefix(url.Host, "192.168.") ||
        strings.HasPrefix(url.Host, "localhost") {
        return false, fmt.Errorf("host not allowed")
    }

    return true, nil
}

// searchForHtmlTitle searches the parsed html document for the title.
func searchForHtmlTitle(n *html.Node) (string, error) {
    if n.Type == html.ElementNode && n.Data == "title" {
        if n.FirstChild.Type != html.TextNode {
            err := fmt.Errorf("child of title not TextNode type")
            return "", err
        }
        return n.FirstChild.Data, nil
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        title, err := searchForHtmlTitle(c)
        if len(title) > 0 || err != nil {
            return title, err
        }
    }
    return "", nil
}
<|endoftext|>


<commit_before>// package editor implements a full-feature line editor.
package editor

import (
	"os"
	"fmt"
	"bufio"
	"unicode"
	"unicode/utf8"
	"./tty"
)

type cell struct {
	rune
	width byte
}

type buffer [][]cell

type Editor struct {
	savedTermios *tty.Termios
	file *os.File
	oldBuf, buf buffer
	line, col, width int
}

type LineRead struct {
	Line string
	Eof bool
	Err error
}

var savedTermios *tty.Termios

func Init(fd int) (*Editor, error) {
	term, err := tty.NewTermiosFromFd(fd)
	if err != nil {
		return nil, fmt.Errorf("Can't get terminal attribute: %s", err)
	}

	editor := &Editor{
		savedTermios: term.Copy(),
		file: os.NewFile(uintptr(fd), "<line editor terminal>"),
		oldBuf: [][]cell{[]cell{}},
	}

	term.SetIcanon(false)
	term.SetEcho(false)
	term.SetMin(1)
	term.SetTime(0)

	err = term.ApplyToFd(fd)
	if err != nil {
		return nil, fmt.Errorf("Can't set up terminal attribute: %s", err)
	}

	fmt.Fprint(editor.file, "\033[?7l")
	return editor, nil
}

func (ed *Editor) Cleanup() error {
	fmt.Fprint(ed.file, "\033[?7h")

	fd := int(ed.file.Fd())
	err := ed.savedTermios.ApplyToFd(fd)
	if err != nil {
		return fmt.Errorf("Can't restore terminal attribute of stdin: %s", err)
	}
	ed.savedTermios = nil
	return nil
}

func (ed *Editor) beep() {
}

func (ed *Editor) tip(s string) {
	fmt.Fprintf(ed.file, "\n%s\033[A", s)
}

func (ed *Editor) tipf(format string, a ...interface{}) {
	ed.tip(fmt.Sprintf(format, a...))
}

func (ed *Editor) clearTip() {
	fmt.Fprintf(ed.file, "\n\033[K\033[A")
}

func (ed *Editor) startBuffer() {
	ed.line = 0
	ed.col = 0
	ed.width = int(tty.GetWinsize(int(ed.file.Fd())).Col)
	ed.buf = [][]cell{make([]cell, ed.width)}
}

func (ed *Editor) commitBuffer() error {
	newlines := len(ed.oldBuf) - 1
	if newlines > 0 {
		fmt.Fprintf(ed.file, "\033[%dA", newlines)
	}
	fmt.Fprintf(ed.file, "\r\033[J")

	for _, line := range ed.buf {
		for _, c := range line {
			_, err := ed.file.WriteString(string(c.rune))
			if err != nil {
				return err
			}
		}
	}
	ed.oldBuf = ed.buf
	return nil
}

func (ed *Editor) appendToLine(c cell) {
	ed.buf[ed.line] = append(ed.buf[ed.line], c)
	ed.col += int(c.width)
}

func (ed *Editor) newline() {
	ed.buf[ed.line] = append(ed.buf[ed.line], cell{rune: '\n'})
	ed.buf = append(ed.buf, make([]cell, ed.width))
	ed.line++
	ed.col = 0
}

func (ed *Editor) write(r rune) {
	wd := wcwidth(r)
	c := cell{r, byte(wd)}

	if ed.col + wd > ed.width {
		ed.newline()
		ed.appendToLine(c)
	} else if ed.col + wd == ed.width {
		ed.appendToLine(c)
		ed.newline()
	} else {
		ed.appendToLine(c)
	}
}

func (ed *Editor) refresh(prompt, text string) error {
	ed.startBuffer()

	for _, r := range prompt {
		ed.write(r)
	}

	var indent int
	if ed.col * 2 < ed.width {
		indent = ed.col
	}

	for _, r := range text {
		ed.write(r)
		if ed.col == 0 {
			// XXX doesn't work on overflowed runes
			for i := 0; i < indent; i++ {
				ed.write(' ')
			}
		}
	}

	return ed.commitBuffer()
}

func (ed *Editor) ReadLine(prompt string) (lr LineRead) {
	stdin := bufio.NewReaderSize(ed.file, 0)
	line := ""

	for {
		// TODO handle err
		ed.refresh(prompt, line)

		r, _, err := stdin.ReadRune()
		if err != nil {
			return LineRead{Err: err}
		}

		switch {
		case r == '\n':
			ed.clearTip()
			fmt.Fprintln(ed.file)
			return LineRead{Line: line}
		case r == 0x7f: // Backspace
			if l := len(line); l > 0 {
				_, w := utf8.DecodeLastRuneInString(line)
				line = line[:l-w]
			} else {
				ed.beep()
			}
		case r == 0x15: // ^U
			line = ""
		case r == 0x4 && len(line) == 0: // ^D
			return LineRead{Eof: true}
		case r == 0x2: // ^B
			fmt.Fprintf(ed.file, "\033[D")
		case r == 0x6: // ^F
			fmt.Fprintf(ed.file, "\033[C")
		case unicode.IsGraphic(r):
			line += string(r)
		default:
			ed.tipf("Non-graphic: %#x", r)
		}
	}

	panic("unreachable")
}
<commit_msg>libdasc/editor: Handle error returned from Editor.refresh<commit_after>// package editor implements a full-feature line editor.
package editor

import (
	"os"
	"fmt"
	"bufio"
	"unicode"
	"unicode/utf8"
	"./tty"
)

type cell struct {
	rune
	width byte
}

type buffer [][]cell

type Editor struct {
	savedTermios *tty.Termios
	file *os.File
	oldBuf, buf buffer
	line, col, width int
}

type LineRead struct {
	Line string
	Eof bool
	Err error
}

var savedTermios *tty.Termios

func Init(fd int) (*Editor, error) {
	term, err := tty.NewTermiosFromFd(fd)
	if err != nil {
		return nil, fmt.Errorf("Can't get terminal attribute: %s", err)
	}

	editor := &Editor{
		savedTermios: term.Copy(),
		file: os.NewFile(uintptr(fd), "<line editor terminal>"),
		oldBuf: [][]cell{[]cell{}},
	}

	term.SetIcanon(false)
	term.SetEcho(false)
	term.SetMin(1)
	term.SetTime(0)

	err = term.ApplyToFd(fd)
	if err != nil {
		return nil, fmt.Errorf("Can't set up terminal attribute: %s", err)
	}

	fmt.Fprint(editor.file, "\033[?7l")
	return editor, nil
}

func (ed *Editor) Cleanup() error {
	fmt.Fprint(ed.file, "\033[?7h")

	fd := int(ed.file.Fd())
	err := ed.savedTermios.ApplyToFd(fd)
	if err != nil {
		return fmt.Errorf("Can't restore terminal attribute of stdin: %s", err)
	}
	ed.savedTermios = nil
	return nil
}

func (ed *Editor) beep() {
}

func (ed *Editor) tip(s string) {
	fmt.Fprintf(ed.file, "\n%s\033[A", s)
}

func (ed *Editor) tipf(format string, a ...interface{}) {
	ed.tip(fmt.Sprintf(format, a...))
}

func (ed *Editor) clearTip() {
	fmt.Fprintf(ed.file, "\n\033[K\033[A")
}

func (ed *Editor) startBuffer() {
	ed.line = 0
	ed.col = 0
	ed.width = int(tty.GetWinsize(int(ed.file.Fd())).Col)
	ed.buf = [][]cell{make([]cell, ed.width)}
}

func (ed *Editor) commitBuffer() error {
	newlines := len(ed.oldBuf) - 1
	if newlines > 0 {
		fmt.Fprintf(ed.file, "\033[%dA", newlines)
	}
	fmt.Fprintf(ed.file, "\r\033[J")

	for _, line := range ed.buf {
		for _, c := range line {
			_, err := ed.file.WriteString(string(c.rune))
			if err != nil {
				return err
			}
		}
	}
	ed.oldBuf = ed.buf
	return nil
}

func (ed *Editor) appendToLine(c cell) {
	ed.buf[ed.line] = append(ed.buf[ed.line], c)
	ed.col += int(c.width)
}

func (ed *Editor) newline() {
	ed.buf[ed.line] = append(ed.buf[ed.line], cell{rune: '\n'})
	ed.buf = append(ed.buf, make([]cell, ed.width))
	ed.line++
	ed.col = 0
}

func (ed *Editor) write(r rune) {
	wd := wcwidth(r)
	c := cell{r, byte(wd)}

	if ed.col + wd > ed.width {
		ed.newline()
		ed.appendToLine(c)
	} else if ed.col + wd == ed.width {
		ed.appendToLine(c)
		ed.newline()
	} else {
		ed.appendToLine(c)
	}
}

func (ed *Editor) refresh(prompt, text string) error {
	ed.startBuffer()

	for _, r := range prompt {
		ed.write(r)
	}

	var indent int
	if ed.col * 2 < ed.width {
		indent = ed.col
	}

	for _, r := range text {
		ed.write(r)
		if ed.col == 0 {
			// XXX doesn't work on overflowed runes
			for i := 0; i < indent; i++ {
				ed.write(' ')
			}
		}
	}

	return ed.commitBuffer()
}

func (ed *Editor) ReadLine(prompt string) (lr LineRead) {
	stdin := bufio.NewReaderSize(ed.file, 0)
	line := ""

	for {
		err := ed.refresh(prompt, line)
		if err != nil {
			return LineRead{Err: err}
		}

		r, _, err := stdin.ReadRune()
		if err != nil {
			return LineRead{Err: err}
		}

		switch {
		case r == '\n':
			ed.clearTip()
			fmt.Fprintln(ed.file)
			return LineRead{Line: line}
		case r == 0x7f: // Backspace
			if l := len(line); l > 0 {
				_, w := utf8.DecodeLastRuneInString(line)
				line = line[:l-w]
			} else {
				ed.beep()
			}
		case r == 0x15: // ^U
			line = ""
		case r == 0x4 && len(line) == 0: // ^D
			return LineRead{Eof: true}
		case r == 0x2: // ^B
			fmt.Fprintf(ed.file, "\033[D")
		case r == 0x6: // ^F
			fmt.Fprintf(ed.file, "\033[C")
		case unicode.IsGraphic(r):
			line += string(r)
		default:
			ed.tipf("Non-graphic: %#x", r)
		}
	}

	panic("unreachable")
}
<|endoftext|>


<commit_before>package lnwire

import (
	"io"

	"github.com/roasbeef/btcd/btcec"
)

// RevokeAndAck is sent by either side once a CommitSig message has been
// received, and validated. This message serves to revoke the prior commitment
// transaction, which was the most up to date version until a CommitSig message
// referencing the specified ChannelPoint was received.  Additionally, this
// message also piggyback's the next revocation hash that Alice should use when
// constructing the Bob's version of the next commitment transaction (which
// would be done before sending a CommitSig message).  This piggybacking allows
// Alice to send the next CommitSig message modifying Bob's commitment
// transaction without first asking for a revocation hash initially.
type RevokeAndAck struct {
	// ChanID uniquely identifies to which currently active channel this
	// RevokeAndAck applies to.
	ChanID ChannelID

	// Revocation is the preimage to the revocation hash of the now prior
	// commitment transaction.
	//
	// If the received revocation is the all zeroes hash ('0' * 32), then
	// this RevokeAndAck is being sent in order to build up the sender's
	// initial revocation window (IRW). In this case, the RevokeAndAck
	// should be added to the receiver's queue of unused revocations to be
	// used to construct future commitment transactions.
	Revocation [32]byte

	// NextRevocationKey is the next revocation key which should be added
	// to the queue of unused revocation keys for the remote peer. This key
	// will be used within the revocation clause for any new commitment
	// transactions created for the remote peer.
	NextRevocationKey *btcec.PublicKey

	// NextRevocationHash is the next revocation hash which should be added
	// to the queue on unused revocation hashes for the remote peer. This
	// revocation hash will be used within any HTLCs included within this
	// next commitment transaction.
	NextRevocationHash [32]byte
}

// NewRevokeAndAck creates a new RevokeAndAck message.
func NewRevokeAndAck() *RevokeAndAck {
	return &RevokeAndAck{}
}

// A compile time check to ensure RevokeAndAck implements the lnwire.Message
// interface.
var _ Message = (*RevokeAndAck)(nil)

// Decode deserializes a serialized RevokeAndAck message stored in the
// passed io.Reader observing the specified protocol version.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error {
	return readElements(r,
		&c.ChanID,
		c.Revocation[:],
		&c.NextRevocationKey,
		c.NextRevocationHash[:],
	)
}

// Encode serializes the target RevokeAndAck into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) Encode(w io.Writer, pver uint32) error {
	return writeElements(w,
		c.ChanID,
		c.Revocation[:],
		c.NextRevocationKey,
		c.NextRevocationHash[:],
	)
}

// MsgType returns the integer uniquely identifying this message type on the
// wire.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MsgType() MessageType {
	return MsgRevokeAndAck
}

// MaxPayloadLength returns the maximum allowed payload size for a
// RevokeAndAck complete message observing the specified protocol version.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MaxPayloadLength(uint32) uint32 {
	// 32 + 32 + 33 + 32
	return 129
}
<commit_msg>lnwire: modify RevokeAndAck to remove NextRevocationHash<commit_after>package lnwire

import (
	"io"

	"github.com/roasbeef/btcd/btcec"
)

// RevokeAndAck is sent by either side once a CommitSig message has been
// received, and validated. This message serves to revoke the prior commitment
// transaction, which was the most up to date version until a CommitSig message
// referencing the specified ChannelPoint was received.  Additionally, this
// message also piggyback's the next revocation hash that Alice should use when
// constructing the Bob's version of the next commitment transaction (which
// would be done before sending a CommitSig message).  This piggybacking allows
// Alice to send the next CommitSig message modifying Bob's commitment
// transaction without first asking for a revocation hash initially.
type RevokeAndAck struct {
	// ChanID uniquely identifies to which currently active channel this
	// RevokeAndAck applies to.
	ChanID ChannelID

	// Revocation is the preimage to the revocation hash of the now prior
	// commitment transaction.
	Revocation [32]byte

	// NextRevocationKey is the next commitment point which should be used
	// for the next commitment transaction the remote peer creates for us.
	// This, in conjunction without revocation base point will be used to
	// create the proper revocation key used within the commitment
	// transaction.
	NextRevocationKey *btcec.PublicKey
}

// NewRevokeAndAck creates a new RevokeAndAck message.
func NewRevokeAndAck() *RevokeAndAck {
	return &RevokeAndAck{}
}

// A compile time check to ensure RevokeAndAck implements the lnwire.Message
// interface.
var _ Message = (*RevokeAndAck)(nil)

// Decode deserializes a serialized RevokeAndAck message stored in the
// passed io.Reader observing the specified protocol version.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) Decode(r io.Reader, pver uint32) error {
	return readElements(r,
		&c.ChanID,
		c.Revocation[:],
		&c.NextRevocationKey,
	)
}

// Encode serializes the target RevokeAndAck into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) Encode(w io.Writer, pver uint32) error {
	return writeElements(w,
		c.ChanID,
		c.Revocation[:],
		c.NextRevocationKey,
	)
}

// MsgType returns the integer uniquely identifying this message type on the
// wire.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MsgType() MessageType {
	return MsgRevokeAndAck
}

// MaxPayloadLength returns the maximum allowed payload size for a RevokeAndAck
// complete message observing the specified protocol version.
//
// This is part of the lnwire.Message interface.
func (c *RevokeAndAck) MaxPayloadLength(uint32) uint32 {
	// 32 + 32 + 33
	return 97
}
<|endoftext|>


<commit_before>package main

import (
    "encoding/json"
    "github.com/garyburd/redigo/redis"
)

type User struct {
    Name     string `json:"name"`
    Password string `json:"password"`
    Method   string `json:"method"`
}

type Storage struct {
    pool *redis.Pool
}

func NewStorage(server string) (*Storage) {
    pool := redis.NewPool(func() (conn redis.Conn, err error) {
        conn, err = redis.Dial("tcp", server)
        return
    }, 3)
    return &Storage{pool}
}

func (s *Storage) Get(key string) (user User, err error) {
    var data []byte
    var conn = s.pool.Get()
    data, err = redis.Bytes(conn.Do("GET", key))
    if err != nil {
        return
    }
    err = json.Unmarshal(data, &user)
    return
}

func (s *Storage) Set(key string, user User) (err error) {
    data, err := json.Marshal(user)
    if err != nil {
        return err
    }
    conn := s.pool.Get()
    _, err = conn.Do("SET", key, data)
    return
}
<commit_msg>gofmt<commit_after>package main

import (
    "encoding/json"
    "github.com/garyburd/redigo/redis"
)

type User struct {
    Name     string `json:"name"`
    Password string `json:"password"`
    Method   string `json:"method"`
}

type Storage struct {
    pool *redis.Pool
}

func NewStorage(server string) *Storage {
    pool := redis.NewPool(func() (conn redis.Conn, err error) {
        conn, err = redis.Dial("tcp", server)
        return
    }, 3)
    return &Storage{pool}
}

func (s *Storage) Get(key string) (user User, err error) {
    var data []byte
    var conn = s.pool.Get()
    data, err = redis.Bytes(conn.Do("GET", key))
    if err != nil {
        return
    }
    err = json.Unmarshal(data, &user)
    return
}

func (s *Storage) Set(key string, user User) (err error) {
    data, err := json.Marshal(user)
    if err != nil {
        return err
    }
    conn := s.pool.Get()
    _, err = conn.Do("SET", key, data)
    return
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

const (
	HELP = `md2xml [-h] file.md
Transform a given Markdown file into XML.
-h        To print this help page.
-x        Print intermediate XHTML output.
file.md   The markdown file to convert.
Note: this program calls xsltproc that must have been installed.`
	STYLESHEET_ARTICLE = `<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:param name="id">ID</xsl:param>
  <xsl:param name="date">DATE</xsl:param>
  <xsl:param name="title">TITLE</xsl:param>
  <xsl:param name="author">AUTHOR</xsl:param>
  <xsl:param name="email">EMAIL</xsl:param>

  <xsl:template match="/xhtml">
    <xsl:text disable-output-escaping="yes">
    <!DOCTYPE article PUBLIC "-//CAFEBABE//DTD blog 1.0//EN"
                             "../dtd/article.dtd">
    </xsl:text>

      <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
      <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
      <xsl:attribute name="author"><xsl:value-of select="$author"/></xsl:attribute>
      <xsl:attribute name="email"><xsl:value-of select="$email"/></xsl:attribute>
      <title><xsl:value-of select="$title"/></title>
      <text>
       <xsl:apply-templates/>
      </text>

  </xsl:template>

  <xsl:template match="h1">
    <sect level="1"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h2">
    <sect level="2"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h3">
    <sect level="3"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h4">
    <sect level="4"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h5">
    <sect level="5"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h6">
    <sect level="6"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="p[@class='caption']">
  </xsl:template>

  <xsl:template match="p[count(text())=0 and count(code)=1]">
    <source><xsl:apply-templates select="code"/></source>
  </xsl:template>

  <xsl:template match="p[count(text())=1 and count(img)=1]">
    <xsl:apply-templates select="img"/>
  </xsl:template>

  <xsl:template match="img">

      <xsl:if test="@alt">
        <xsl:attribute name="title">
          <xsl:value-of select="@alt"/>
        </xsl:attribute>
      </xsl:if>
      <xsl:if test="@title">
        <xsl:attribute name="title">
          <xsl:value-of select="@title"/>
        </xsl:attribute>
      </xsl:if>

  </xsl:template>

  <xsl:template match="p">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="ul">
    <list><xsl:apply-templates/></list>
  </xsl:template>

  <xsl:template match="ol">
    <enum><xsl:apply-templates/></enum>
  </xsl:template>

  <xsl:template match="li">
    <item><xsl:apply-templates/></item>
  </xsl:template>

  <xsl:template match="table">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="th">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tr">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="td">
    <co><xsl:apply-templates/></co>
  </xsl:template>

  <xsl:template match="pre">
    <source><xsl:apply-templates/></source>
  </xsl:template>

  <xsl:template match="em">
    <term><xsl:apply-templates/></term>
  </xsl:template>

  <xsl:template match="strong">
    <imp><xsl:apply-templates/></imp>
  </xsl:template>

  <xsl:template match="a">
    <link url="{@href}"><xsl:apply-templates/></link>
  </xsl:template>

</xsl:stylesheet>`
	STYLESHEET_BLOG = `<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:param name="id">ID</xsl:param>
  <xsl:param name="date">DATE</xsl:param>
  <xsl:param name="title">TITLE</xsl:param>

  <xsl:template match="/xhtml">
    <xsl:text disable-output-escaping="yes">
    <!DOCTYPE blog PUBLIC "-//CAFEBABE//DTD blog 1.0//EN"
                          "../dtd/blog.dtd">
    </xsl:text>
    <blog>
      <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
      <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
      <title><xsl:value-of select="$title"/></title>
      <xsl:apply-templates/>
    </blog>
  </xsl:template>

  <xsl:template match="h1">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h2">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h3">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h4">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h5">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h6">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="p[@class='caption']">
  </xsl:template>

  <xsl:template match="p[count(text())=0 and count(code)=1]">
    <source><xsl:apply-templates select="code"/></source>
  </xsl:template>

  <xsl:template match="p[count(text())=1 and count(img)=1]">
    <xsl:apply-templates select="img"/>
  </xsl:template>

  <xsl:template match="img">

      <xsl:if test="@alt">
        <xsl:attribute name="title">
          <xsl:value-of select="@alt"/>
        </xsl:attribute>
      </xsl:if>
      <xsl:if test="@title">
        <xsl:attribute name="title">
          <xsl:value-of select="@title"/>
        </xsl:attribute>
      </xsl:if>

  </xsl:template>

  <xsl:template match="p">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="ul">
    <list><xsl:apply-templates/></list>
  </xsl:template>

  <xsl:template match="ol">
    <enum><xsl:apply-templates/></enum>
  </xsl:template>

  <xsl:template match="li">
    <item><xsl:apply-templates/></item>
  </xsl:template>

  <xsl:template match="table">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="th">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tr">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="td">
    <co><xsl:apply-templates/></co>
  </xsl:template>

  <xsl:template match="pre">
    <source><xsl:apply-templates/></source>
  </xsl:template>

  <xsl:template match="em">
    <term><xsl:apply-templates/></term>
  </xsl:template>

  <xsl:template match="strong">
    <imp><xsl:apply-templates/></imp>
  </xsl:template>

  <xsl:template match="a">
    <link url="{@href}"><xsl:apply-templates/></link>
  </xsl:template>

</xsl:stylesheet>`
	XHTML_HEADER = "<xhtml>\n"
	XHTML_FOOTER = "\n</xhtml>"
)

func processXsl(xmlFile string, data map[string]string, article bool) []byte {
	xslFile, err := ioutil.TempFile("/tmp", "md2xsl-")
	if err != nil {
		panic(err)
	}
	stylesheet := STYLESHEET_ARTICLE
	if !article {
		stylesheet = STYLESHEET_BLOG
	}
	err = ioutil.WriteFile(xslFile.Name(), []byte(stylesheet), 0755)
	if err != nil {
		panic(err)
	}
	defer os.Remove(xslFile.Name())
	params := make([]string, 0, 2+3*len(data))
	for name, value := range data {
		params = append(params, "--stringparam")
		params = append(params, name)
		params = append(params, value)
	}
	params = append(params, xslFile.Name())
	params = append(params, xmlFile)
	command := exec.Command("xsltproc", params...)
	result, err := command.CombinedOutput()
	if err != nil {
	 print(result)
		panic(err)
	}
	return result
}

func markdown2xhtml(markdown string) []byte {
	mdFile, err := ioutil.TempFile("/tmp", "md2xsl-")
	if err != nil {
		panic(err)
	}
	defer os.Remove(mdFile.Name())
	ioutil.WriteFile(mdFile.Name(), []byte(markdown), 0x755)
	command := exec.Command("pandoc", mdFile.Name(), "-f", "markdown", "-t", "html")
	result, err := command.CombinedOutput()
	if err != nil {
		panic(err)
	}
	return []byte(XHTML_HEADER + string(result) + XHTML_FOOTER)
}

func markdownData(text string) (map[string]string, string) {
	data := make(map[string]string)
	lines := strings.Split(text, "\n")
	var limit int
	for index, line := range lines {
		if strings.HasPrefix(line, "% ") && strings.Index(line, ":") >= 0 {
			name := strings.TrimSpace(line[2:strings.Index(line, ":")])
			value := strings.TrimSpace(line[strings.Index(line, ":")+1 : len(line)])
			data[name] = value
		} else {
			limit = index
			break
		}
	}
	return data, strings.Join(lines[limit:len(lines)], "\n")
}

func escapeXml(source string) string {
	source = strings.Replace(source, "&", "&", -1)
	source = strings.Replace(source, "<", "<", -1)
	return source
}

func processFile(filename string, printXhtml bool, article bool) string {
	source, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	data, markdown := markdownData(string(source))
	markdown = escapeXml(markdown)
	xhtml := markdown2xhtml(markdown)
	if printXhtml {
		return string(xhtml)
	}
	xmlFile, err := ioutil.TempFile("/tmp", "md2xml-")
	if err != nil {
		panic(err)
	}
	defer os.Remove(xmlFile.Name())
	ioutil.WriteFile(xmlFile.Name(), xhtml, 0755)
	result := processXsl(xmlFile.Name(), data, article)
	return string(result)
}

func main() {
	xhtml := false
	article := false
	if len(os.Args) < 2 {
		fmt.Println(HELP)
		os.Exit(1)
	}
	for _, arg := range os.Args[1:] {
		if arg == "-h" || os.Args[1] == "--help" {
			fmt.Println(HELP)
			os.Exit(0)
		} else if arg == "-x" || arg == "--xhtml" {
			xhtml = true
		} else if arg == "-a" || arg == "--article" {
			article = true
		} else {
			fmt.Println(processFile(arg, xhtml, article))
		}
	}
}
<commit_msg>Fixed images<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
)

const (
	HELP = `md2xml [-h] file.md
Transform a given Markdown file into XML.
-h        To print this help page.
-x        Print intermediate XHTML output.
file.md   The markdown file to convert.
Note: this program calls xsltproc that must have been installed.`
	STYLESHEET_ARTICLE = `<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:param name="id">ID</xsl:param>
  <xsl:param name="date">DATE</xsl:param>
  <xsl:param name="title">TITLE</xsl:param>
  <xsl:param name="author">AUTHOR</xsl:param>
  <xsl:param name="email">EMAIL</xsl:param>

  <xsl:template match="/xhtml">
    <xsl:text disable-output-escaping="yes">
    <!DOCTYPE article PUBLIC "-//CAFEBABE//DTD blog 1.0//EN"
                             "../dtd/article.dtd">
    </xsl:text>

      <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
      <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
      <xsl:attribute name="author"><xsl:value-of select="$author"/></xsl:attribute>
      <xsl:attribute name="email"><xsl:value-of select="$email"/></xsl:attribute>
      <title><xsl:value-of select="$title"/></title>
      <text>
       <xsl:apply-templates/>
      </text>

  </xsl:template>

  <xsl:template match="h1">
    <sect level="1"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h2">
    <sect level="2"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h3">
    <sect level="3"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h4">
    <sect level="4"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h5">
    <sect level="5"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="h6">
    <sect level="6"><title><xsl:value-of select="."/></title></sect>
  </xsl:template>

  <xsl:template match="p[@class='caption']">
  </xsl:template>

  <xsl:template match="p[count(text())=0 and count(code)=1]">
    <source><xsl:apply-templates select="code"/></source>
  </xsl:template>

  <xsl:template match="p[count(text())=1 and count(img)=1]">
    <xsl:apply-templates select="img"/>
  </xsl:template>

  <xsl:template match="img">

      <xsl:if test="@title">
        <title><xsl:value-of select="@title"/></title>
      </xsl:if>

  </xsl:template>

  <xsl:template match="p">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="ul">
    <list><xsl:apply-templates/></list>
  </xsl:template>

  <xsl:template match="ol">
    <enum><xsl:apply-templates/></enum>
  </xsl:template>

  <xsl:template match="li">
    <item><xsl:apply-templates/></item>
  </xsl:template>

  <xsl:template match="table">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="th">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tr">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="td">
    <co><xsl:apply-templates/></co>
  </xsl:template>

  <xsl:template match="pre">
    <source><xsl:apply-templates/></source>
  </xsl:template>

  <xsl:template match="em">
    <term><xsl:apply-templates/></term>
  </xsl:template>

  <xsl:template match="strong">
    <imp><xsl:apply-templates/></imp>
  </xsl:template>

  <xsl:template match="a">
    <link url="{@href}"><xsl:apply-templates/></link>
  </xsl:template>

</xsl:stylesheet>`
	STYLESHEET_BLOG = `<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

  <xsl:output method="xml" encoding="UTF-8"/>
  <xsl:param name="id">ID</xsl:param>
  <xsl:param name="date">DATE</xsl:param>
  <xsl:param name="title">TITLE</xsl:param>

  <xsl:template match="/xhtml">
    <xsl:text disable-output-escaping="yes">
    <!DOCTYPE blog PUBLIC "-//CAFEBABE//DTD blog 1.0//EN"
                          "../dtd/blog.dtd">
    </xsl:text>
    <blog>
      <xsl:attribute name="id"><xsl:value-of select="$id"/></xsl:attribute>
      <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
      <title><xsl:value-of select="$title"/></title>
      <xsl:apply-templates/>
    </blog>
  </xsl:template>

  <xsl:template match="h1">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h2">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h3">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h4">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h5">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="h6">

<imp><xsl:value-of select="."/></imp>

  </xsl:template>

  <xsl:template match="p[@class='caption']">
  </xsl:template>

  <xsl:template match="p[count(text())=0 and count(code)=1]">
    <source><xsl:apply-templates select="code"/></source>
  </xsl:template>

  <xsl:template match="p[count(text())=1 and count(img)=1]">
    <xsl:apply-templates select="img"/>
  </xsl:template>

  <xsl:template match="img">

      <xsl:if test="@title">
        <title><xsl:value-of select="@title"/></title>
      </xsl:if>

  </xsl:template>

  <xsl:template match="p">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="ul">
    <list><xsl:apply-templates/></list>
  </xsl:template>

  <xsl:template match="ol">
    <enum><xsl:apply-templates/></enum>
  </xsl:template>

  <xsl:template match="li">
    <item><xsl:apply-templates/></item>
  </xsl:template>

  <xsl:template match="table">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="th">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tr">

<xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="td">
    <co><xsl:apply-templates/></co>
  </xsl:template>

  <xsl:template match="pre">
    <source><xsl:apply-templates/></source>
  </xsl:template>

  <xsl:template match="em">
    <term><xsl:apply-templates/></term>
  </xsl:template>

  <xsl:template match="strong">
    <imp><xsl:apply-templates/></imp>
  </xsl:template>

  <xsl:template match="a">
    <link url="{@href}"><xsl:apply-templates/></link>
  </xsl:template>

</xsl:stylesheet>`
	XHTML_HEADER = "<xhtml>\n"
	XHTML_FOOTER = "\n</xhtml>"
)

func processXsl(xmlFile string, data map[string]string, article bool) []byte {
	xslFile, err := ioutil.TempFile("/tmp", "md2xsl-")
	if err != nil {
		panic(err)
	}
	stylesheet := STYLESHEET_ARTICLE
	if !article {
		stylesheet = STYLESHEET_BLOG
	}
	err = ioutil.WriteFile(xslFile.Name(), []byte(stylesheet), 0755)
	if err != nil {
		panic(err)
	}
	defer os.Remove(xslFile.Name())
	params := make([]string, 0, 2+3*len(data))
	for name, value := range data {
		params = append(params, "--stringparam")
		params = append(params, name)
		params = append(params, value)
	}
	params = append(params, xslFile.Name())
	params = append(params, xmlFile)
	command := exec.Command("xsltproc", params...)
	result, err := command.CombinedOutput()
	if err != nil {
	 print(result)
		panic(err)
	}
	return result
}

func markdown2xhtml(markdown string) []byte {
	mdFile, err := ioutil.TempFile("/tmp", "md2xsl-")
	if err != nil {
		panic(err)
	}
	defer os.Remove(mdFile.Name())
	ioutil.WriteFile(mdFile.Name(), []byte(markdown), 0x755)
	command := exec.Command("pandoc", mdFile.Name(), "-f", "markdown", "-t", "html")
	result, err := command.CombinedOutput()
	if err != nil {
		panic(err)
	}
	return []byte(XHTML_HEADER + string(result) + XHTML_FOOTER)
}

func markdownData(text string) (map[string]string, string) {
	data := make(map[string]string)
	lines := strings.Split(text, "\n")
	var limit int
	for index, line := range lines {
		if strings.HasPrefix(line, "% ") && strings.Index(line, ":") >= 0 {
			name := strings.TrimSpace(line[2:strings.Index(line, ":")])
			value := strings.TrimSpace(line[strings.Index(line, ":")+1 : len(line)])
			data[name] = value
		} else {
			limit = index
			break
		}
	}
	return data, strings.Join(lines[limit:len(lines)], "\n")
}

func processFile(filename string, printXhtml bool, article bool) string {
	source, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	data, markdown := markdownData(string(source))
	xhtml := markdown2xhtml(markdown)
	if printXhtml {
		return string(xhtml)
	}
	xmlFile, err := ioutil.TempFile("/tmp", "md2xml-")
	if err != nil {
		panic(err)
	}
	defer os.Remove(xmlFile.Name())
	ioutil.WriteFile(xmlFile.Name(), xhtml, 0755)
	result := processXsl(xmlFile.Name(), data, article)
	return string(result)
}

func main() {
	xhtml := false
	article := false
	if len(os.Args) < 2 {
		fmt.Println(HELP)
		os.Exit(1)
	}
	for _, arg := range os.Args[1:] {
		if arg == "-h" || os.Args[1] == "--help" {
			fmt.Println(HELP)
			os.Exit(0)
		} else if arg == "-x" || arg == "--xhtml" {
			xhtml = true
		} else if arg == "-a" || arg == "--article" {
			article = true
		} else {
			fmt.Println(processFile(arg, xhtml, article))
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"gopkg.in/errgo.v1"
	"gopkg.in/yaml.v2"
)

type session struct {
	Name        string            `yaml:"name"`
	SetupScript string            `yaml:"setup-script"`
	Environment map[string]string `yaml:"environment"`
	Cwd         string            `yaml:"cwd"`
	Windows     []window          `yaml:"windows"`
	Focus       string            `yaml:"focus"`
}

type window struct {
	Name       string   `yaml:"name"`
	Command    string   `yaml:"command"`
	Cwd        string   `yaml:"cwd"`
	Keystrokes []string `yaml:"keystrokes"`
}

func die(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, errgo.Details(err))
		os.Exit(1)
	}
}

func main() {
	die(run())
}

func run() error {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, "usage: %s <session.yaml file>", os.Args[0])
		return errgo.New("missing session file argument")
	}

	name, err := locateSession(os.Args[1])
	if err != nil {
		return errgo.Mask(err)
	}

	session, err := newSession(name)
	if err != nil {
		return errgo.Mask(err)
	}

	for k, v := range session.Environment {
		os.Setenv(k, os.ExpandEnv(v))
	}

	log.Println(os.Environ())

	err = session.setupScript()
	if err != nil {
		return errgo.Notef(err, "failed to execute setup script")
	}

	err = session.create()
	if err != nil {
		return errgo.Mask(err)
	}

	var focus int
	for i, window := range session.Windows {
		if i > 0 {
			err = session.createWindow(i, &window)
			if err != nil {
				return errgo.Mask(err)
			}
		}

		err = session.sendKeys(&window)
		if err != nil {
			return errgo.Mask(err)
		}

		if session.Focus == window.Name {
			focus = i
		}
	}
	err = session.focus(focus)
	if err != nil {
		return errgo.Mask(err)
	}

	err = session.tmux("attach", "-t", session.Name)
	return errgo.Mask(err)
}

func locateSession(name string) (string, error) {
	if _, err := os.Stat(name); err == nil {
		return name, nil
	} else if !os.IsNotExist(err) {
		return "", errgo.Notef(err, "failed to open session file %q", name)
	}

	configDir := os.Getenv("XDG_CONFIG_HOME")
	if configDir == "" {
		configDir = filepath.Join(os.Getenv("HOME"), ".config")
	}

	tmuxgConfigDir := filepath.Join(configDir, "tmuxg")
	err := os.MkdirAll(tmuxgConfigDir, 0644)
	if err != nil {
		return "", errgo.Notef(err, "failed to create config directory %q", tmuxgConfigDir)
	}

	path := filepath.Join(tmuxgConfigDir, name+".yaml")
	if _, err := os.Stat(path); err != nil {
		return "", errgo.Notef(err, "failed to resolve session %q file %q", name, path)
	}
	return path, nil
}

func newSession(path string) (*session, error) {
	var s session

	contents, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, errgo.Notef(err, "failed to read session file")
	}
	err = yaml.Unmarshal(contents, &s)
	if err != nil {
		return nil, errgo.Notef(err, "failed to parse session file")
	}
	return &s, nil
}

func (s *session) tmux(args ...string) error {
	c := exec.Command("tmux", append([]string{"-L", s.Name}, args...)...)
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = os.ExpandEnv(s.Cwd)
	log.Printf("%v", c)
	return errgo.Mask(c.Run())
}

func (s *session) setupScript() error {
	if s.SetupScript == "" {
		return nil
	}

	f, err := ioutil.TempFile("", "tmuxg-setup")
	if err != nil {
		return errgo.Notef(err, "failed to create temporary file for script")
	}
	defer os.Remove(f.Name())
	defer f.Close()

	_, err = fmt.Fprintf(f, "%s", strings.TrimSpace(s.SetupScript))
	if err != nil {
		return errgo.Notef(err, "failed to write temporary script file")
	}
	err = f.Close()
	if err != nil {
		return errgo.Notef(err, "error closing temporary script file")
	}
	err = os.Chmod(f.Name(), 0700)
	if err != nil {
		return errgo.Notef(err, "error setting temporary script executable")
	}

	c := exec.Command(f.Name())
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	return errgo.Mask(c.Run())
}

func (s *session) create() error {
	if len(s.Windows) == 0 {
		return errgo.New("no windows configured for this session!")
	}
	err := s.tmux("new-session", "-d", "-s", s.Name,
		os.ExpandEnv(s.Windows[0].Command))
	if err != nil {
		return errgo.Notef(err, "failed to start tmux session")
	}

	var keys []string
	for k, v := range s.Environment {
		err = s.tmux("set-environment", k, os.ExpandEnv(v))
		if err != nil {
			return errgo.Notef(err, "failed to set environment variable %q", k)
		}
		keys = append(keys, k)
	}

	return nil
}

func (s *session) createWindow(i int, w *window) error {
	cwd := w.Cwd
	if cwd == "" {
		cwd = s.Cwd
	}
	cwd = os.ExpandEnv(cwd)
	err := s.tmux("new-window", "-d", "-t", fmt.Sprintf("%s:%d", s.Name, i),
		"-c", cwd, os.ExpandEnv(w.Command))
	if err != nil {
		return errgo.Notef(err, "failed to create window %q", w.Name)
	}
	return nil
}

func (s *session) sendKeys(w *window) error {
	if len(w.Keystrokes) > 0 {
		err := s.tmux(append([]string{"send-keys"}, w.Keystrokes...)...)
		if err != nil {
			return errgo.Notef(err, "failed to send keystrokes to window %q", w.Name)
		}
	}
	return nil
}

func (s *session) focus(i int) error {
	err := s.tmux("select-window", "-t", fmt.Sprintf("%s:%d", s.Name, i))
	if err != nil {
		return errgo.Notef(err, "failed to set window focus")
	}
	return nil
}
<commit_msg>Use config argument as a file only if it's a file (not a directory).<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"gopkg.in/errgo.v1"
	"gopkg.in/yaml.v2"
)

type session struct {
	Name        string            `yaml:"name"`
	SetupScript string            `yaml:"setup-script"`
	Environment map[string]string `yaml:"environment"`
	Cwd         string            `yaml:"cwd"`
	Windows     []window          `yaml:"windows"`
	Focus       string            `yaml:"focus"`
}

type window struct {
	Name       string   `yaml:"name"`
	Command    string   `yaml:"command"`
	Cwd        string   `yaml:"cwd"`
	Keystrokes []string `yaml:"keystrokes"`
}

func die(err error) {
	if err != nil {
		fmt.Fprintln(os.Stderr, errgo.Details(err))
		os.Exit(1)
	}
}

func main() {
	die(run())
}

func run() error {
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, "usage: %s <session.yaml file>", os.Args[0])
		return errgo.New("missing session file argument")
	}

	name, err := locateSession(os.Args[1])
	if err != nil {
		return errgo.Mask(err)
	}

	session, err := newSession(name)
	if err != nil {
		return errgo.Mask(err)
	}

	for k, v := range session.Environment {
		os.Setenv(k, os.ExpandEnv(v))
	}

	log.Println(os.Environ())

	err = session.setupScript()
	if err != nil {
		return errgo.Notef(err, "failed to execute setup script")
	}

	err = session.create()
	if err != nil {
		return errgo.Mask(err)
	}

	var focus int
	for i, window := range session.Windows {
		if i > 0 {
			err = session.createWindow(i, &window)
			if err != nil {
				return errgo.Mask(err)
			}
		}

		err = session.sendKeys(&window)
		if err != nil {
			return errgo.Mask(err)
		}

		if session.Focus == window.Name {
			focus = i
		}
	}
	err = session.focus(focus)
	if err != nil {
		return errgo.Mask(err)
	}

	err = session.tmux("attach", "-t", session.Name)
	return errgo.Mask(err)
}

func locateSession(name string) (string, error) {
	if info, err := os.Stat(name); err == nil && !info.IsDir() {
		return name, nil
	} else if err != nil && !os.IsNotExist(err) {
		return "", errgo.Notef(err, "failed to open session file %q", name)
	}

	configDir := os.Getenv("XDG_CONFIG_HOME")
	if configDir == "" {
		configDir = filepath.Join(os.Getenv("HOME"), ".config")
	}

	tmuxgConfigDir := filepath.Join(configDir, "tmuxg")
	err := os.MkdirAll(tmuxgConfigDir, 0644)
	if err != nil {
		return "", errgo.Notef(err, "failed to create config directory %q", tmuxgConfigDir)
	}

	path := filepath.Join(tmuxgConfigDir, name+".yaml")
	if _, err := os.Stat(path); err != nil {
		return "", errgo.Notef(err, "failed to resolve session %q file %q", name, path)
	}
	return path, nil
}

func newSession(path string) (*session, error) {
	var s session

	contents, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, errgo.Notef(err, "failed to read session file")
	}
	err = yaml.Unmarshal(contents, &s)
	if err != nil {
		return nil, errgo.Notef(err, "failed to parse session file")
	}
	return &s, nil
}

func (s *session) tmux(args ...string) error {
	c := exec.Command("tmux", append([]string{"-L", s.Name}, args...)...)
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = os.ExpandEnv(s.Cwd)
	log.Printf("%v", c)
	return errgo.Mask(c.Run())
}

func (s *session) setupScript() error {
	if s.SetupScript == "" {
		return nil
	}

	f, err := ioutil.TempFile("", "tmuxg-setup")
	if err != nil {
		return errgo.Notef(err, "failed to create temporary file for script")
	}
	defer os.Remove(f.Name())
	defer f.Close()

	_, err = fmt.Fprintf(f, "%s", strings.TrimSpace(s.SetupScript))
	if err != nil {
		return errgo.Notef(err, "failed to write temporary script file")
	}
	err = f.Close()
	if err != nil {
		return errgo.Notef(err, "error closing temporary script file")
	}
	err = os.Chmod(f.Name(), 0700)
	if err != nil {
		return errgo.Notef(err, "error setting temporary script executable")
	}

	c := exec.Command(f.Name())
	c.Stdin = os.Stdin
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	return errgo.Mask(c.Run())
}

func (s *session) create() error {
	if len(s.Windows) == 0 {
		return errgo.New("no windows configured for this session!")
	}
	err := s.tmux("new-session", "-d", "-s", s.Name,
		os.ExpandEnv(s.Windows[0].Command))
	if err != nil {
		return errgo.Notef(err, "failed to start tmux session")
	}

	var keys []string
	for k, v := range s.Environment {
		err = s.tmux("set-environment", k, os.ExpandEnv(v))
		if err != nil {
			return errgo.Notef(err, "failed to set environment variable %q", k)
		}
		keys = append(keys, k)
	}

	return nil
}

func (s *session) createWindow(i int, w *window) error {
	cwd := w.Cwd
	if cwd == "" {
		cwd = s.Cwd
	}
	cwd = os.ExpandEnv(cwd)
	err := s.tmux("new-window", "-d", "-t", fmt.Sprintf("%s:%d", s.Name, i),
		"-c", cwd, os.ExpandEnv(w.Command))
	if err != nil {
		return errgo.Notef(err, "failed to create window %q", w.Name)
	}
	return nil
}

func (s *session) sendKeys(w *window) error {
	if len(w.Keystrokes) > 0 {
		err := s.tmux(append([]string{"send-keys"}, w.Keystrokes...)...)
		if err != nil {
			return errgo.Notef(err, "failed to send keystrokes to window %q", w.Name)
		}
	}
	return nil
}

func (s *session) focus(i int) error {
	err := s.tmux("select-window", "-t", fmt.Sprintf("%s:%d", s.Name, i))
	if err != nil {
		return errgo.Notef(err, "failed to set window focus")
	}
	return nil
}
<|endoftext|>


<commit_before>package gorethink

import (
	"flag"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"testing"
	"time"

	test "gopkg.in/check.v1"
)

var sess *Session
var debug = flag.Bool("gorethink.debug", false, "print query trees")
var url, db, authKey string

func init() {
	flag.Parse()

	// If the test is being run by wercker look for the rethink url
	url = os.Getenv("RETHINKDB_URL")
	if url == "" {
		url = "localhost:28015"
	}

	db = os.Getenv("RETHINKDB_DB")
	if db == "" {
		db = "test"
	}

	// Needed for running tests for RethinkDB with a non-empty authkey
	authKey = os.Getenv("RETHINKDB_AUTHKEY")
}

//
// Begin TestMain(), Setup, Teardown
//
func testBenchmarkSetup() {

	var err error

	bDbName = "benchmark"
	bTableName = "benchmarks"

	bSess, err = Connect(ConnectOpts{
		Address:  "localhost:28015",
		Database: bDbName,
		MaxIdle:  50,
		MaxOpen:  50,
	})

	if err != nil {
		log.Fatalln(err.Error())
	}

	DbDrop(bDbName).Exec(bSess)
	DbCreate(bDbName).Exec(bSess)

	Db(bDbName).TableDrop(bTableName).Run(bSess)
	Db(bDbName).TableCreate(bTableName).Run(bSess)

}

func testBenchmarkTeardown() {
	Db(bDbName).TableDrop(bTableName).Run(bSess)
	bSess.Close()
}

// stubs
func testSetup()    {}
func testTeardown() {}

func TestMain(m *testing.M) {
	// seed randomness for use with tests
	rand.Seed(time.Now().UTC().UnixNano())
	testSetup()
	testBenchmarkSetup()
	res := m.Run()
	testTeardown()
	testBenchmarkTeardown()
	os.Exit(res)
}

//
// End TestMain(), Setup, Teardown
//

// Hook up gocheck into the gotest runner.
func Test(t *testing.T) { test.TestingT(t) }

type RethinkSuite struct{}

var _ = test.Suite(&RethinkSuite{})

func (s *RethinkSuite) SetUpSuite(c *test.C) {
	var err error
	sess, err = Connect(ConnectOpts{
		Address: url,
		AuthKey: authKey,
	})
	c.Assert(err, test.IsNil)
}

func (s *RethinkSuite) TearDownSuite(c *test.C) {
	sess.Close()
}

// Expressions used in tests
var now = time.Now()
var arr = []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}
var darr = []interface{}{1, 1, 2, 2, 3, 3, 5, 5, 6}
var narr = []interface{}{
	1, 2, 3, 4, 5, 6, []interface{}{
		7.1, 7.2, 7.3,
	},
}
var obj = map[string]interface{}{"a": 1, "b": 2, "c": 3}
var nobj = map[string]interface{}{
	"A": 1,
	"B": 2,
	"C": map[string]interface{}{
		"1": 3,
		"2": 4,
	},
}
var noDupNumObjList = []interface{}{
	map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
	map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
	map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
	map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
	map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
	map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
	map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
}
var objList = []interface{}{
	map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
	map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
	map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
	map[string]interface{}{"id": 4, "g1": 2, "g2": 3, "num": 0},
	map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
	map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
	map[string]interface{}{"id": 7, "g1": 1, "g2": 2, "num": 0},
	map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
	map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
}
var nameList = []interface{}{
	map[string]interface{}{"id": 1, "first_name": "John", "last_name": "Smith", "gender": "M"},
	map[string]interface{}{"id": 2, "first_name": "Jane", "last_name": "Smith", "gender": "F"},
}
var defaultObjList = []interface{}{
	map[string]interface{}{"a": 1},
	map[string]interface{}{},
}
var joinTable1 = []interface{}{
	map[string]interface{}{"id": 0, "name": "bob"},
	map[string]interface{}{"id": 1, "name": "tom"},
	map[string]interface{}{"id": 2, "name": "joe"},
}
var joinTable2 = []interface{}{
	map[string]interface{}{"id": 0, "title": "goof"},
	map[string]interface{}{"id": 2, "title": "lmoe"},
}
var joinTable3 = []interface{}{
	map[string]interface{}{"it": 0, "title": "goof"},
	map[string]interface{}{"it": 2, "title": "lmoe"},
}

type TStr string
type TMap map[string]interface{}

type T struct {
	A string `gorethink:"id, omitempty"`
	B int
	C int `gorethink:"-"`
	D map[string]interface{}
	E []interface{}
	F X
}

type SimpleT struct {
	A string
	B int
}

type X struct {
	XA int
	XB string
	XC []string
	XD Y
	XE TStr
	XF []TStr
}

type Y struct {
	YA int
	YB map[string]interface{}
	YC map[string]string
	YD TMap
}

type PseudoTypes struct {
	T time.Time
	B []byte
}

var str = T{
	A: "A",
	B: 1,
	C: 1,
	D: map[string]interface{}{
		"D1": 1,
		"D2": "2",
	},
	E: []interface{}{
		"E1", "E2", "E3", 4,
	},
	F: X{
		XA: 2,
		XB: "B",
		XC: []string{"XC1", "XC2"},
		XD: Y{
			YA: 3,
			YB: map[string]interface{}{
				"1": "1",
				"2": "2",
				"3": 3,
			},
			YC: map[string]string{
				"YC1": "YC1",
			},
			YD: TMap{
				"YD1": "YD1",
			},
		},
		XE: "XE",
		XF: []TStr{
			"XE1", "XE2",
		},
	},
}

func (s *RethinkSuite) BenchmarkExpr(c *test.C) {
	for i := 0; i < c.N; i++ {
		// Test query
		query := Expr(true)
		err := query.Exec(sess)
		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkNoReplyExpr(c *test.C) {
	for i := 0; i < c.N; i++ {
		// Test query
		query := Expr(true)
		err := query.Exec(sess, ExecOpts{NoReply: true})
		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkGet(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id": i,
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		n := rand.Intn(100)

		// Test query
		var response interface{}
		query := Db("test").Table("TestMany").Get(n)
		res, err := query.Run(sess)
		c.Assert(err, test.IsNil)

		err = res.One(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, jsonEquals, map[string]interface{}{"id": n})
	}
}

func (s *RethinkSuite) BenchmarkGetStruct(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id":   i,
			"name": "Object 1",
			"Attrs": []interface{}{map[string]interface{}{
				"Name":  "attr 1",
				"Value": "value 1",
			}},
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		n := rand.Intn(100)

		// Test query
		var resObj object
		query := Db("test").Table("TestMany").Get(n)
		res, err := query.Run(sess)
		c.Assert(err, test.IsNil)

		err = res.One(&resObj)

		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkSelectMany(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id": i,
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		// Test query
		res, err := Db("test").Table("TestMany").Run(sess)
		c.Assert(err, test.IsNil)

		var response []map[string]interface{}
		err = res.All(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, test.HasLen, 100)
	}
}

func (s *RethinkSuite) BenchmarkSelectManyStruct(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id":   i,
			"name": "Object 1",
			"Attrs": []interface{}{map[string]interface{}{
				"Name":  "attr 1",
				"Value": "value 1",
			}},
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		// Test query
		res, err := Db("test").Table("TestMany").Run(sess)
		c.Assert(err, test.IsNil)

		var response []object
		err = res.All(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, test.HasLen, 100)
	}
}

func doConcurrentTest(c *test.C, ct func()) {
	maxProcs, numReqs := 1, 150
	if testing.Short() {
		maxProcs, numReqs = 4, 50
	}
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))

	var wg sync.WaitGroup
	wg.Add(numReqs)

	reqs := make(chan bool)
	defer close(reqs)

	for i := 0; i < maxProcs*2; i++ {
		go func() {
			for _ = range reqs {
				ct()
				if c.Failed() {
					wg.Done()
					continue
				}
				wg.Done()
			}
		}()
	}

	for i := 0; i < numReqs; i++ {
		reqs <- true
	}

	wg.Wait()
}
<commit_msg>Fixed wercker build<commit_after>package gorethink

import (
	"flag"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sync"
	"testing"
	"time"

	test "gopkg.in/check.v1"
)

var sess *Session
var debug = flag.Bool("gorethink.debug", false, "print query trees")
var url, db, authKey string

func init() {
	flag.Parse()

	// If the test is being run by wercker look for the rethink url
	url = os.Getenv("RETHINKDB_URL")
	if url == "" {
		url = "localhost:28015"
	}

	db = os.Getenv("RETHINKDB_DB")
	if db == "" {
		db = "test"
	}

	// Needed for running tests for RethinkDB with a non-empty authkey
	authKey = os.Getenv("RETHINKDB_AUTHKEY")
}

//
// Begin TestMain(), Setup, Teardown
//
func testBenchmarkSetup() {

	var err error

	bDbName = "benchmark"
	bTableName = "benchmarks"

	bSess, err = Connect(ConnectOpts{
		Address:  url,
		Database: bDbName,
		MaxIdle:  50,
		MaxOpen:  50,
	})

	if err != nil {
		log.Fatalln(err.Error())
	}

	DbDrop(bDbName).Exec(bSess)
	DbCreate(bDbName).Exec(bSess)

	Db(bDbName).TableDrop(bTableName).Run(bSess)
	Db(bDbName).TableCreate(bTableName).Run(bSess)

}

func testBenchmarkTeardown() {
	Db(bDbName).TableDrop(bTableName).Run(bSess)
	bSess.Close()
}

// stubs
func testSetup()    {}
func testTeardown() {}

func TestMain(m *testing.M) {
	// seed randomness for use with tests
	rand.Seed(time.Now().UTC().UnixNano())
	testSetup()
	testBenchmarkSetup()
	res := m.Run()
	testTeardown()
	testBenchmarkTeardown()
	os.Exit(res)
}

//
// End TestMain(), Setup, Teardown
//

// Hook up gocheck into the gotest runner.
func Test(t *testing.T) { test.TestingT(t) }

type RethinkSuite struct{}

var _ = test.Suite(&RethinkSuite{})

func (s *RethinkSuite) SetUpSuite(c *test.C) {
	var err error
	sess, err = Connect(ConnectOpts{
		Address: url,
		AuthKey: authKey,
	})
	c.Assert(err, test.IsNil)
}

func (s *RethinkSuite) TearDownSuite(c *test.C) {
	sess.Close()
}

// Expressions used in tests
var now = time.Now()
var arr = []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}
var darr = []interface{}{1, 1, 2, 2, 3, 3, 5, 5, 6}
var narr = []interface{}{
	1, 2, 3, 4, 5, 6, []interface{}{
		7.1, 7.2, 7.3,
	},
}
var obj = map[string]interface{}{"a": 1, "b": 2, "c": 3}
var nobj = map[string]interface{}{
	"A": 1,
	"B": 2,
	"C": map[string]interface{}{
		"1": 3,
		"2": 4,
	},
}
var noDupNumObjList = []interface{}{
	map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
	map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
	map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
	map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
	map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
	map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
	map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
}
var objList = []interface{}{
	map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
	map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
	map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
	map[string]interface{}{"id": 4, "g1": 2, "g2": 3, "num": 0},
	map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
	map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
	map[string]interface{}{"id": 7, "g1": 1, "g2": 2, "num": 0},
	map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
	map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
}
var nameList = []interface{}{
	map[string]interface{}{"id": 1, "first_name": "John", "last_name": "Smith", "gender": "M"},
	map[string]interface{}{"id": 2, "first_name": "Jane", "last_name": "Smith", "gender": "F"},
}
var defaultObjList = []interface{}{
	map[string]interface{}{"a": 1},
	map[string]interface{}{},
}
var joinTable1 = []interface{}{
	map[string]interface{}{"id": 0, "name": "bob"},
	map[string]interface{}{"id": 1, "name": "tom"},
	map[string]interface{}{"id": 2, "name": "joe"},
}
var joinTable2 = []interface{}{
	map[string]interface{}{"id": 0, "title": "goof"},
	map[string]interface{}{"id": 2, "title": "lmoe"},
}
var joinTable3 = []interface{}{
	map[string]interface{}{"it": 0, "title": "goof"},
	map[string]interface{}{"it": 2, "title": "lmoe"},
}

type TStr string
type TMap map[string]interface{}

type T struct {
	A string `gorethink:"id, omitempty"`
	B int
	C int `gorethink:"-"`
	D map[string]interface{}
	E []interface{}
	F X
}

type SimpleT struct {
	A string
	B int
}

type X struct {
	XA int
	XB string
	XC []string
	XD Y
	XE TStr
	XF []TStr
}

type Y struct {
	YA int
	YB map[string]interface{}
	YC map[string]string
	YD TMap
}

type PseudoTypes struct {
	T time.Time
	B []byte
}

var str = T{
	A: "A",
	B: 1,
	C: 1,
	D: map[string]interface{}{
		"D1": 1,
		"D2": "2",
	},
	E: []interface{}{
		"E1", "E2", "E3", 4,
	},
	F: X{
		XA: 2,
		XB: "B",
		XC: []string{"XC1", "XC2"},
		XD: Y{
			YA: 3,
			YB: map[string]interface{}{
				"1": "1",
				"2": "2",
				"3": 3,
			},
			YC: map[string]string{
				"YC1": "YC1",
			},
			YD: TMap{
				"YD1": "YD1",
			},
		},
		XE: "XE",
		XF: []TStr{
			"XE1", "XE2",
		},
	},
}

func (s *RethinkSuite) BenchmarkExpr(c *test.C) {
	for i := 0; i < c.N; i++ {
		// Test query
		query := Expr(true)
		err := query.Exec(sess)
		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkNoReplyExpr(c *test.C) {
	for i := 0; i < c.N; i++ {
		// Test query
		query := Expr(true)
		err := query.Exec(sess, ExecOpts{NoReply: true})
		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkGet(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id": i,
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		n := rand.Intn(100)

		// Test query
		var response interface{}
		query := Db("test").Table("TestMany").Get(n)
		res, err := query.Run(sess)
		c.Assert(err, test.IsNil)

		err = res.One(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, jsonEquals, map[string]interface{}{"id": n})
	}
}

func (s *RethinkSuite) BenchmarkGetStruct(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id":   i,
			"name": "Object 1",
			"Attrs": []interface{}{map[string]interface{}{
				"Name":  "attr 1",
				"Value": "value 1",
			}},
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		n := rand.Intn(100)

		// Test query
		var resObj object
		query := Db("test").Table("TestMany").Get(n)
		res, err := query.Run(sess)
		c.Assert(err, test.IsNil)

		err = res.One(&resObj)

		c.Assert(err, test.IsNil)
	}
}

func (s *RethinkSuite) BenchmarkSelectMany(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id": i,
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		// Test query
		res, err := Db("test").Table("TestMany").Run(sess)
		c.Assert(err, test.IsNil)

		var response []map[string]interface{}
		err = res.All(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, test.HasLen, 100)
	}
}

func (s *RethinkSuite) BenchmarkSelectManyStruct(c *test.C) {
	// Ensure table + database exist
	DbCreate("test").RunWrite(sess)
	Db("test").TableCreate("TestMany").RunWrite(sess)
	Db("test").Table("TestMany").Delete().RunWrite(sess)

	// Insert rows
	data := []interface{}{}
	for i := 0; i < 100; i++ {
		data = append(data, map[string]interface{}{
			"id":   i,
			"name": "Object 1",
			"Attrs": []interface{}{map[string]interface{}{
				"Name":  "attr 1",
				"Value": "value 1",
			}},
		})
	}
	Db("test").Table("TestMany").Insert(data).Run(sess)

	for i := 0; i < c.N; i++ {
		// Test query
		res, err := Db("test").Table("TestMany").Run(sess)
		c.Assert(err, test.IsNil)

		var response []object
		err = res.All(&response)

		c.Assert(err, test.IsNil)
		c.Assert(response, test.HasLen, 100)
	}
}

func doConcurrentTest(c *test.C, ct func()) {
	maxProcs, numReqs := 1, 150
	if testing.Short() {
		maxProcs, numReqs = 4, 50
	}
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))

	var wg sync.WaitGroup
	wg.Add(numReqs)

	reqs := make(chan bool)
	defer close(reqs)

	for i := 0; i < maxProcs*2; i++ {
		go func() {
			for _ = range reqs {
				ct()
				if c.Failed() {
					wg.Done()
					continue
				}
				wg.Done()
			}
		}()
	}

	for i := 0; i < numReqs; i++ {
		reqs <- true
	}

	wg.Wait()
}
<|endoftext|>