Skip to content

Instantly share code, notes, and snippets.

@ethanquix
Created February 20, 2020 18:02
Show Gist options
  • Save ethanquix/87b2a5462ce6856d988499aebf27b004 to your computer and use it in GitHub Desktop.
Save ethanquix/87b2a5462ce6856d988499aebf27b004 to your computer and use it in GitHub Desktop.
package utils
import (
"encoding/json"
"fmt"
"github.com/mxmCherry/openrtb"
)
// Merge 2 string arrays but remove any duplicate element
func MergeStringArray(a []string, b []string) []string {
out := append(a, b...)
seen := make(map[string]struct{}, len(out))
j := 0
for _, s := range out {
if _, ok := seen[s]; ok {
continue
}
seen[s] = struct{}{}
out[j] = s
j++
}
return out[:j]
}
//We only return the non empty string
func MergeString(a string, b string) string {
if a == "" {
return b
}
return a
}
//We take the bigger int || MAY BE TOTALLY WRONG !!!
func MergeInt8(a int8, b int8) int8 {
if a > b {
return a
}
return b
}
//We take the bigger int || MAY BE TOTALLY WRONG !!!
func MergeInt64(a int64, b int64) int64 {
if a > b {
return a
}
return b
}
//We take the bigger int || MAY BE TOTALLY WRONG !!!
func MergeFloat64(a float64, b float64) float64 {
if a > b {
return a
}
return b
}
//We take the bigger int || MAY BE TOTALLY WRONG !!!
func MergeUint64(a uint64, b uint64) uint64 {
if a > b {
return a
}
return b
}
//TODO Difficult one, we only return the first one || MAY BE TOTALLY WRONG
func MergeJSONRawMessage(a json.RawMessage, b json.RawMessage) json.RawMessage {
return a
}
func MergePublisher(a *openrtb.Publisher, b *openrtb.Publisher) *openrtb.Publisher {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Publisher{}
out.ID = MergeString(a.ID, b.ID)
out.Name = MergeString(a.Name, b.Name)
out.Cat = MergeStringArray(a.Cat, b.Cat)
out.Domain = MergeString(a.Domain, b.Domain)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeProducer(a *openrtb.Producer, b *openrtb.Producer) *openrtb.Producer {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Producer{}
out.ID = MergeString(a.ID, b.ID)
out.Name = MergeString(a.Name, b.Name)
out.Cat = MergeStringArray(a.Cat, b.Cat)
out.Domain = MergeString(a.Domain, b.Domain)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeProductionQuality(a *openrtb.ProductionQuality, b *openrtb.ProductionQuality) *openrtb.ProductionQuality {
if a.Val() > b.Val() {
return a
}
return b
}
func MergeContentContext(a openrtb.ContentContext, b openrtb.ContentContext) openrtb.ContentContext {
if a > b {
return a
}
return b
}
//func MergeData(a *openrtb.Data, b *openrtb.Data) *openrtb.Data {
// out := &openrtb.Data{}
//
// return out
//}
// Actually we only take the bigger... TODO
func MergeDataArray(a []openrtb.Data, b []openrtb.Data) []openrtb.Data {
if len(a) > len(b) {
return a
}
return b
}
func MergeContent(a *openrtb.Content, b *openrtb.Content) *openrtb.Content {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Content{}
out.ID = MergeString(a.ID, b.ID)
out.Episode = MergeUint64(a.Episode, b.Episode)
out.Title = MergeString(a.Title, b.Title)
out.Series = MergeString(a.Series, b.Series)
out.Season = MergeString(a.Season, b.Season)
out.Artist = MergeString(a.Artist, b.Artist)
out.Genre = MergeString(a.Genre, b.Genre)
out.Album = MergeString(a.Album, b.Album)
out.ISRC = MergeString(a.ISRC, b.ISRC)
out.Producer = MergeProducer(a.Producer, b.Producer)
fmt.Println("Domain final")
fmt.Println(out.Producer.Domain)
out.URL = MergeString(a.URL, b.URL)
out.Cat = MergeStringArray(a.Cat, b.Cat)
out.ProdQ = MergeProductionQuality(a.ProdQ, b.ProdQ)
out.VideoQuality = MergeProductionQuality(a.VideoQuality, b.VideoQuality)
out.Context = MergeContentContext(a.Context, b.Context)
out.ContentRating = MergeString(a.ContentRating, b.ContentRating)
out.UserRating = MergeString(a.UserRating, b.UserRating)
out.QAGMediaRating = openrtb.IQGMediaRating(MergeInt8(int8(a.QAGMediaRating), int8(b.QAGMediaRating)))
out.Keywords = MergeString(a.Keywords, b.Keywords)
out.LiveStream = MergeInt8(a.LiveStream, b.LiveStream)
out.SourceRelationship = MergeInt8(a.SourceRelationship, b.SourceRelationship)
out.Len = MergeInt64(a.Len, b.Len)
out.Language = MergeString(a.Language, b.Language)
out.Embeddable = MergeInt8(a.Embeddable, b.Embeddable)
out.Data = MergeDataArray(a.Data, b.Data)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeSite(a *openrtb.Site, b *openrtb.Site) *openrtb.Site {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Site{}
out.ID = MergeString(a.ID, b.ID)
out.Name = MergeString(a.Name, b.Name)
out.Domain = MergeString(a.Domain, b.Domain)
out.Cat = MergeStringArray(a.Cat, b.Cat)
out.SectionCat = MergeStringArray(a.SectionCat, b.SectionCat)
out.PageCat = MergeStringArray(a.PageCat, b.PageCat)
out.Page = MergeString(a.Page, b.Page)
out.Ref = MergeString(a.Ref, b.Ref)
out.Search = MergeString(a.Search, b.Search)
out.Mobile = MergeInt8(a.Mobile, b.Mobile)
out.PrivacyPolicy = MergeInt8(a.PrivacyPolicy, b.PrivacyPolicy)
out.Publisher = MergePublisher(a.Publisher, b.Publisher)
out.Content = MergeContent(a.Content, b.Content)
out.Keywords = MergeString(a.Keywords, b.Keywords)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
//TODO for now we only return the one with the most length
func MergeImpArray(a []openrtb.Imp, b []openrtb.Imp) []openrtb.Imp {
if len(a) > len(b) {
return a
}
return b
}
func MergeApp(a *openrtb.App, b *openrtb.App) *openrtb.App {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.App{}
out.ID = MergeString(a.ID, b.ID)
out.Name = MergeString(a.Name, b.Name)
out.Bundle = MergeString(a.Bundle, b.Bundle)
out.Domain = MergeString(a.Domain, b.Domain)
out.StoreURL = MergeString(a.StoreURL, b.StoreURL)
out.Cat = MergeStringArray(a.Cat, b.Cat)
out.SectionCat = MergeStringArray(a.SectionCat, b.SectionCat)
out.PageCat = MergeStringArray(a.PageCat, b.PageCat)
out.Ver = MergeString(a.Ver, b.Ver)
out.PrivacyPolicy = MergeInt8(a.PrivacyPolicy, b.PrivacyPolicy)
out.Paid = MergeInt8(a.Paid, b.Paid)
out.Publisher = MergePublisher(a.Publisher, b.Publisher)
out.Content = MergeContent(a.Content, b.Content)
out.Keywords = MergeString(a.Keywords, b.Keywords)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeGeo(a *openrtb.Geo, b *openrtb.Geo) *openrtb.Geo {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Geo{}
out.Lat = MergeFloat64(a.Lat, b.Lat)
out.Lon = MergeFloat64(a.Lon, b.Lon)
out.Type = openrtb.LocationType(MergeInt8(int8(a.Type), int8(b.Type)))
out.Accuracy = MergeUint64(a.Accuracy, b.Accuracy)
out.LastFix = MergeInt64(a.LastFix, b.LastFix)
out.IPService = openrtb.IPLocationService(MergeInt8(int8(a.IPService), int8(b.IPService)))
out.Country = MergeString(a.Country, b.Country)
out.Region = MergeString(a.Region, b.Region)
out.RegionFIPS104 = MergeString(a.RegionFIPS104, b.RegionFIPS104)
out.Metro = MergeString(a.Metro, b.Metro)
out.City = MergeString(a.City, b.City)
out.ZIP = MergeString(a.ZIP, b.ZIP)
out.UTCOffset = MergeInt64(a.UTCOffset, b.UTCOffset)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeConnectionType(a *openrtb.ConnectionType, b *openrtb.ConnectionType) *openrtb.ConnectionType {
if a.Val() > b.Val() {
return a
}
return b
}
func MergeDevice(a *openrtb.Device, b *openrtb.Device) *openrtb.Device {
if a == nil {
return b
}
if b == nil {
return a
}
out := &openrtb.Device{}
out.UA = MergeString(a.UA, b.UA)
out.Geo = MergeGeo(a.Geo, b.Geo)
out.DNT = MergeInt8(a.DNT, b.DNT)
out.Lmt = MergeInt8(a.Lmt, b.Lmt)
out.IP = MergeString(a.IP, b.IP)
out.IPv6 = MergeString(a.IPv6, b.IPv6)
out.DeviceType = openrtb.DeviceType(MergeInt8(int8(a.DeviceType), int8(b.DeviceType)))
out.Make = MergeString(a.Make, b.Make)
out.Model = MergeString(a.Model, b.Model)
out.OS = MergeString(a.OS, b.OS)
out.OSV = MergeString(a.OSV, b.OSV)
out.HWV = MergeString(a.HWV, b.HWV)
out.H = MergeUint64(a.H, b.H)
out.W = MergeUint64(a.W, b.W)
out.PPI = MergeUint64(a.PPI, b.PPI)
out.PxRatio = MergeFloat64(a.PxRatio, b.PxRatio)
out.JS = MergeInt8(a.JS, b.JS)
out.GeoFetch = MergeInt8(a.GeoFetch, b.GeoFetch)
out.FlashVer = MergeString(a.FlashVer, b.FlashVer)
out.Language = MergeString(a.Language, b.Language)
out.Carrier = MergeString(a.Carrier, b.Carrier)
out.MCCMNC = MergeString(a.MCCMNC, b.MCCMNC)
out.ConnectionType = MergeConnectionType(a.ConnectionType, b.ConnectionType)
out.IFA = MergeString(a.IFA, b.IFA)
out.DIDSHA1 = MergeString(a.DIDSHA1, b.DIDSHA1)
out.DIDMD5 = MergeString(a.DIDMD5, b.DIDMD5)
out.DPIDSHA1 = MergeString(a.DPIDSHA1, b.DPIDSHA1)
out.DPIDMD5 = MergeString(a.DPIDMD5, b.DPIDMD5)
out.MACSHA1 = MergeString(a.MACSHA1, b.MACSHA1)
out.MACMD5 = MergeString(a.MACMD5, b.MACMD5)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeUser(a *openrtb.User, b *openrtb.User) *openrtb.User {
out := &openrtb.User{}
out.ID = MergeString(a.ID, b.ID)
out.BuyerUID = MergeString(a.BuyerUID, b.BuyerUID)
out.Yob = MergeInt64(a.Yob, b.Yob)
out.Gender = MergeString(a.Gender, b.Gender)
//TODO read desc, is keywords comma separated, need to splice them , fusion, rm duplicate, etc, ...
out.Keywords = MergeString(a.Keywords, b.Keywords)
out.CustomData = MergeString(a.CustomData, b.CustomData)
out.Geo = MergeGeo(a.Geo, b.Geo)
out.Data = MergeDataArray(a.Data, b.Data)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeSource(a *openrtb.Source, b *openrtb.Source) *openrtb.Source {
out := &openrtb.Source{}
out.FD = MergeInt8(a.FD, b.FD)
out.TID = MergeString(a.TID, b.TID)
out.PChain = MergeString(a.PChain, b.PChain)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeRegs(a *openrtb.Regs, b *openrtb.Regs) *openrtb.Regs {
out := &openrtb.Regs{}
out.COPPA = MergeInt8(a.COPPA, b.COPPA)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
func MergeBidRequest(a *openrtb.BidRequest, b *openrtb.BidRequest) *openrtb.BidRequest {
out := &openrtb.BidRequest{}
if a.ID == "" {
out.ID = b.ID
} else {
out.ID = a.ID
}
//For the IMPS, we only take the bigger one for now, we need to change this but today the only case where we have IMPS is if we have a POST of Ortb object.
out.Imp = MergeImpArray(a.Imp, b.Imp)
out.Site = MergeSite(a.Site, b.Site)
out.App = MergeApp(a.App, b.App)
out.Device = MergeDevice(a.Device, b.Device)
out.User = MergeUser(a.User, b.User)
out.Test = MergeInt8(a.Test, b.Test)
out.AT = MergeInt64(a.AT, b.AT)
out.TMax = MergeInt64(a.TMax, b.TMax)
out.WSeat = MergeStringArray(a.WSeat, b.WSeat)
out.BSeat = MergeStringArray(a.BSeat, b.BSeat)
out.AllImps = MergeInt8(a.AllImps, b.AllImps)
out.Cur = MergeStringArray(a.Cur, b.Cur)
out.WLang = MergeStringArray(a.WLang, b.WLang)
out.BCat = MergeStringArray(a.BCat, b.BCat)
out.BAdv = MergeStringArray(a.BAdv, b.BAdv)
out.BApp = MergeStringArray(a.BApp, b.BApp)
out.Source = MergeSource(a.Source, b.Source)
out.Regs = MergeRegs(a.Regs, b.Regs)
out.Ext = MergeJSONRawMessage(a.Ext, b.Ext)
return out
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment