Browse Source

Xml generation by worker

Vova Tkach 5 years ago
parent
commit
cbdebd732a
2 changed files with 156 additions and 161 deletions
  1. 8 2
      main.go
  2. 148 159
      xml.go

+ 8 - 2
main.go

@@ -71,8 +71,7 @@ func main() {
 	wImageGen := image_generator(consts.ParamWwwDir)
 	wImageGen := image_generator(consts.ParamWwwDir)
 
 
 	// Xml generation
 	// Xml generation
-	xml_cl_ch, xml_cl_stop := xml_start(consts.ParamWwwDir, mpool)
-	defer xml_stop(xml_cl_ch, xml_cl_stop)
+	wXmlGen := xml_generator(consts.ParamWwwDir, mpool)
 
 
 	// Init mounted resources
 	// Init mounted resources
 	res := resource.New()
 	res := resource.New()
@@ -283,6 +282,12 @@ func main() {
 		var errs []string
 		var errs []string
 
 
 		// ---
 		// ---
+		if wXmlGen, ok := (*o)[4].(*worker.Worker); ok {
+			if err := wXmlGen.Shutdown(ctx); err != nil {
+				errs = append(errs, fmt.Sprintf("(%T): %s", wXmlGen, err.Error()))
+			}
+		}
+
 		if wImageGen, ok := (*o)[3].(*worker.Worker); ok {
 		if wImageGen, ok := (*o)[3].(*worker.Worker); ok {
 			if err := wImageGen.Shutdown(ctx); err != nil {
 			if err := wImageGen.Shutdown(ctx); err != nil {
 				errs = append(errs, fmt.Sprintf("(%T): %s", wImageGen, err.Error()))
 				errs = append(errs, fmt.Sprintf("(%T): %s", wImageGen, err.Error()))
@@ -329,6 +334,7 @@ func main() {
 				mpool,
 				mpool,
 				wSessCl,
 				wSessCl,
 				wImageGen,
 				wImageGen,
+				wXmlGen,
 				res,
 				res,
 				stat,
 				stat,
 				mods,
 				mods,

+ 148 - 159
xml.go

@@ -1,6 +1,7 @@
 package main
 package main
 
 
 import (
 import (
+	"context"
 	"fmt"
 	"fmt"
 	"html"
 	"html"
 	"io/ioutil"
 	"io/ioutil"
@@ -12,9 +13,92 @@ import (
 	"golang-fave/engine/sqlw"
 	"golang-fave/engine/sqlw"
 	"golang-fave/engine/wrapper/config"
 	"golang-fave/engine/wrapper/config"
 	"golang-fave/utils"
 	"golang-fave/utils"
+
+	"github.com/vladimirok5959/golang-worker/worker"
 )
 )
 
 
-func xml_gen_currencies(db *sqlw.DB, conf *config.Config) string {
+func xml_generator(www_dir string, mp *mysqlpool.MySqlPool) *worker.Worker {
+	return worker.New(func(ctx context.Context, w *worker.Worker, o *[]worker.Iface) {
+		if www_dir, ok := (*o)[0].(string); ok {
+			if mp, ok := (*o)[1].(*mysqlpool.MySqlPool); ok {
+				xml_loop(ctx, www_dir, mp)
+			}
+		}
+		select {
+		case <-ctx.Done():
+		case <-time.After(5 * time.Second):
+			return
+		}
+	}, &[]worker.Iface{
+		www_dir,
+		mp,
+	})
+}
+
+func xml_loop(ctx context.Context, www_dir string, mp *mysqlpool.MySqlPool) {
+	dirs, err := ioutil.ReadDir(www_dir)
+	if err == nil {
+		for _, dir := range dirs {
+			select {
+			case <-ctx.Done():
+				return
+			default:
+				if mp != nil {
+					target_dir := strings.Join([]string{www_dir, dir.Name()}, string(os.PathSeparator))
+					if utils.IsDirExists(target_dir) {
+						xml_detect(ctx, target_dir, dir.Name(), mp)
+					}
+				}
+			}
+		}
+	}
+}
+
+func xml_detect(ctx context.Context, dir, host string, mp *mysqlpool.MySqlPool) {
+	db := mp.Get(host)
+	if db != nil {
+		trigger := strings.Join([]string{dir, "tmp", "trigger.xml.run"}, string(os.PathSeparator))
+		if utils.IsFileExists(trigger) {
+			if err := db.Ping(); err == nil {
+				xml_create(ctx, dir, host, db)
+				os.Remove(trigger)
+			}
+		}
+	}
+}
+
+func xml_create(ctx context.Context, dir, host string, db *sqlw.DB) {
+	conf := config.ConfigNew()
+	if err := conf.ConfigRead(strings.Join([]string{dir, "config", "config.json"}, string(os.PathSeparator))); err == nil {
+		if (*conf).API.XML.Enabled == 1 {
+			if file, err := os.Create(strings.Join([]string{dir, "htdocs", "products.xml"}, string(os.PathSeparator))); err == nil {
+				file.Write([]byte(xml_generate(ctx, db, conf)))
+				file.Close()
+			} else {
+				fmt.Printf("Xml generation error (file): %v\n", err)
+			}
+		}
+	} else {
+		fmt.Printf("Xml generation error (config): %v\n", err)
+	}
+}
+
+func xml_generate(ctx context.Context, db *sqlw.DB, conf *config.Config) string {
+	return `<?xml version="1.0" encoding="UTF-8"?>` +
+		`<!DOCTYPE yml_catalog SYSTEM "shops.dtd">` +
+		`<yml_catalog date="` + time.Unix(int64(time.Now().Unix()), 0).Format("2006-01-02 15:04") + `">` +
+		`<shop>` +
+		`<name>` + html.EscapeString((*conf).API.XML.Name) + `</name>` +
+		`<company>` + html.EscapeString((*conf).API.XML.Company) + `</company>` +
+		`<url>` + html.EscapeString((*conf).API.XML.Url) + `</url>` +
+		`<currencies>` + xml_gen_currencies(ctx, db, conf) + `</currencies>` +
+		`<categories>` + xml_gen_categories(ctx, db, conf) + `</categories>` +
+		`<offers>` + xml_gen_offers(ctx, db, conf) + `</offers>` +
+		`</shop>` +
+		`</yml_catalog>`
+}
+
+func xml_gen_currencies(ctx context.Context, db *sqlw.DB, conf *config.Config) string {
 	result := ``
 	result := ``
 	rows, err := db.Query(
 	rows, err := db.Query(
 		`SELECT
 		`SELECT
@@ -43,7 +127,7 @@ func xml_gen_currencies(db *sqlw.DB, conf *config.Config) string {
 	return result
 	return result
 }
 }
 
 
-func xml_gen_categories(db *sqlw.DB, conf *config.Config) string {
+func xml_gen_categories(ctx context.Context, db *sqlw.DB, conf *config.Config) string {
 	result := ``
 	result := ``
 	rows, err := db.Query(
 	rows, err := db.Query(
 		`SELECT
 		`SELECT
@@ -102,7 +186,67 @@ func xml_gen_categories(db *sqlw.DB, conf *config.Config) string {
 	return result
 	return result
 }
 }
 
 
-func xml_gen_offer_pictures(db *sqlw.DB, conf *config.Config, product_id, parent_id int) string {
+func xml_gen_offers(ctx context.Context, db *sqlw.DB, conf *config.Config) string {
+	result := ``
+	rows, err := db.Query(
+		`SELECT
+			shop_products.id,
+			shop_currencies.code,
+			shop_products.price,
+			shop_products.name,
+			shop_products.alias,
+			shop_products.vendor,
+			shop_products.quantity,
+			shop_products.category,
+			shop_products.content,
+			IFNULL(shop_products.parent_id, 0),
+			shop_products.price_old,
+			shop_products.price_promo
+		FROM
+			shop_products
+			LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
+		WHERE
+			shop_products.active = 1 AND
+			shop_products.category > 1
+		ORDER BY
+			shop_products.id
+		;`,
+	)
+	if err == nil {
+		defer rows.Close()
+		values := make([]string, 12)
+		scan := make([]interface{}, len(values))
+		for i := range values {
+			scan[i] = &values[i]
+		}
+		for rows.Next() {
+			err = rows.Scan(scan...)
+			if err == nil {
+				result += `<offer id="` + html.EscapeString(string(values[0])) + `" available="true">`
+				result += `<url>` + html.EscapeString((*conf).API.XML.Url) + `shop/` + html.EscapeString(string(values[4])) + `/</url>`
+				result += `<price>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[2])), "%.2f") + `</price>`
+				if utils.StrToFloat64(string(values[10])) > 0 {
+					result += `<price_old>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[10])), "%.2f") + `</price_old>`
+				}
+				if utils.StrToFloat64(string(values[11])) > 0 {
+					result += `<price_promo>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[11])), "%.2f") + `</price_promo>`
+				}
+				result += `<currencyId>` + html.EscapeString(string(values[1])) + `</currencyId>`
+				result += `<categoryId>` + html.EscapeString(string(values[7])) + `</categoryId>`
+				result += xml_gen_offer_pictures(ctx, db, conf, utils.StrToInt(string(values[0])), utils.StrToInt(string(values[9])))
+				result += `<vendor>` + html.EscapeString(string(values[5])) + `</vendor>`
+				result += `<stock_quantity>` + html.EscapeString(string(values[6])) + `</stock_quantity>`
+				result += `<name>` + html.EscapeString(string(values[3])) + ` ` + html.EscapeString(string(values[0])) + `</name>`
+				result += `<description><![CDATA[` + string(values[8]) + `]]></description>`
+				result += xml_gen_offer_attributes(ctx, db, conf, utils.StrToInt(string(values[0])))
+				result += `</offer>`
+			}
+		}
+	}
+	return result
+}
+
+func xml_gen_offer_pictures(ctx context.Context, db *sqlw.DB, conf *config.Config, product_id, parent_id int) string {
 	result := ``
 	result := ``
 	if rows, err := db.Query(
 	if rows, err := db.Query(
 		`SELECT
 		`SELECT
@@ -164,7 +308,7 @@ func xml_gen_offer_pictures(db *sqlw.DB, conf *config.Config, product_id, parent
 	return result
 	return result
 }
 }
 
 
-func xml_gen_offer_attributes(db *sqlw.DB, conf *config.Config, product_id int) string {
+func xml_gen_offer_attributes(ctx context.Context, db *sqlw.DB, conf *config.Config, product_id int) string {
 	result := ``
 	result := ``
 	filter_ids := []int{}
 	filter_ids := []int{}
 	filter_names := map[int]string{}
 	filter_names := map[int]string{}
@@ -209,158 +353,3 @@ func xml_gen_offer_attributes(db *sqlw.DB, conf *config.Config, product_id int)
 	}
 	}
 	return result
 	return result
 }
 }
-
-func xml_gen_offers(db *sqlw.DB, conf *config.Config) string {
-	result := ``
-	rows, err := db.Query(
-		`SELECT
-			shop_products.id,
-			shop_currencies.code,
-			shop_products.price,
-			shop_products.name,
-			shop_products.alias,
-			shop_products.vendor,
-			shop_products.quantity,
-			shop_products.category,
-			shop_products.content,
-			IFNULL(shop_products.parent_id, 0),
-			shop_products.price_old,
-			shop_products.price_promo
-		FROM
-			shop_products
-			LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
-		WHERE
-			shop_products.active = 1 AND
-			shop_products.category > 1
-		ORDER BY
-			shop_products.id
-		;`,
-	)
-	if err == nil {
-		defer rows.Close()
-		values := make([]string, 12)
-		scan := make([]interface{}, len(values))
-		for i := range values {
-			scan[i] = &values[i]
-		}
-		for rows.Next() {
-			err = rows.Scan(scan...)
-			if err == nil {
-				result += `<offer id="` + html.EscapeString(string(values[0])) + `" available="true">`
-				result += `<url>` + html.EscapeString((*conf).API.XML.Url) + `shop/` + html.EscapeString(string(values[4])) + `/</url>`
-				result += `<price>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[2])), "%.2f") + `</price>`
-				if utils.StrToFloat64(string(values[10])) > 0 {
-					result += `<price_old>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[10])), "%.2f") + `</price_old>`
-				}
-				if utils.StrToFloat64(string(values[11])) > 0 {
-					result += `<price_promo>` + utils.Float64ToStrF(utils.StrToFloat64(string(values[11])), "%.2f") + `</price_promo>`
-				}
-				result += `<currencyId>` + html.EscapeString(string(values[1])) + `</currencyId>`
-				result += `<categoryId>` + html.EscapeString(string(values[7])) + `</categoryId>`
-				result += xml_gen_offer_pictures(db, conf, utils.StrToInt(string(values[0])), utils.StrToInt(string(values[9])))
-				result += `<vendor>` + html.EscapeString(string(values[5])) + `</vendor>`
-				result += `<stock_quantity>` + html.EscapeString(string(values[6])) + `</stock_quantity>`
-				result += `<name>` + html.EscapeString(string(values[3])) + ` ` + html.EscapeString(string(values[0])) + `</name>`
-				result += `<description><![CDATA[` + string(values[8]) + `]]></description>`
-				result += xml_gen_offer_attributes(db, conf, utils.StrToInt(string(values[0])))
-				result += `</offer>`
-			}
-		}
-	}
-	return result
-}
-
-func xml_generate(db *sqlw.DB, conf *config.Config) string {
-	return `<?xml version="1.0" encoding="UTF-8"?>` +
-		`<!DOCTYPE yml_catalog SYSTEM "shops.dtd">` +
-		`<yml_catalog date="` + time.Unix(int64(time.Now().Unix()), 0).Format("2006-01-02 15:04") + `">` +
-		`<shop>` +
-		`<name>` + html.EscapeString((*conf).API.XML.Name) + `</name>` +
-		`<company>` + html.EscapeString((*conf).API.XML.Company) + `</company>` +
-		`<url>` + html.EscapeString((*conf).API.XML.Url) + `</url>` +
-		`<currencies>` + xml_gen_currencies(db, conf) + `</currencies>` +
-		`<categories>` + xml_gen_categories(db, conf) + `</categories>` +
-		`<offers>` + xml_gen_offers(db, conf) + `</offers>` +
-		`</shop>` +
-		`</yml_catalog>`
-}
-
-func xml_create(dir, host string, db *sqlw.DB) {
-	conf := config.ConfigNew()
-	if err := conf.ConfigRead(strings.Join([]string{dir, "config", "config.json"}, string(os.PathSeparator))); err == nil {
-		if (*conf).API.XML.Enabled == 1 {
-			if file, err := os.Create(strings.Join([]string{dir, "htdocs", "products.xml"}, string(os.PathSeparator))); err == nil {
-				file.Write([]byte(xml_generate(db, conf)))
-				file.Close()
-			} else {
-				fmt.Printf("Xml generation error (file): %v\n", err)
-			}
-		}
-	} else {
-		fmt.Printf("Xml generation error (config): %v\n", err)
-	}
-}
-
-func xml_detect(dir, host string, mp *mysqlpool.MySqlPool) {
-	db := mp.Get(host)
-	if db != nil {
-		trigger := strings.Join([]string{dir, "tmp", "trigger.xml.run"}, string(os.PathSeparator))
-		if utils.IsFileExists(trigger) {
-			if err := db.Ping(); err == nil {
-				xml_create(dir, host, db)
-				os.Remove(trigger)
-			}
-		}
-	}
-}
-
-func xml_loop(www_dir string, stop chan bool, mp *mysqlpool.MySqlPool) {
-	dirs, err := ioutil.ReadDir(www_dir)
-	if err == nil {
-		for _, dir := range dirs {
-			select {
-			case <-stop:
-				break
-			default:
-				if mp != nil {
-					target_dir := strings.Join([]string{www_dir, dir.Name()}, string(os.PathSeparator))
-					if utils.IsDirExists(target_dir) {
-						xml_detect(target_dir, dir.Name(), mp)
-					}
-				}
-			}
-		}
-	}
-}
-
-func xml_start(www_dir string, mp *mysqlpool.MySqlPool) (chan bool, chan bool) {
-	ch := make(chan bool)
-	stop := make(chan bool)
-	go func() {
-		for {
-			select {
-			case <-time.After(5 * time.Second):
-				// Run every 5 seconds
-				xml_loop(www_dir, stop, mp)
-			case <-ch:
-				ch <- true
-				return
-			}
-		}
-	}()
-	return ch, stop
-}
-
-func xml_stop(ch, stop chan bool) {
-	for {
-		select {
-		case stop <- true:
-		case ch <- true:
-			<-ch
-			return
-		case <-time.After(3 * time.Second):
-			fmt.Println("Xml error: force exit by timeout after 3 seconds")
-			return
-		}
-	}
-}