Skip to content

Commit

Permalink
Bids 1582/generic ad module (#1910)
Browse files Browse the repository at this point in the history
* (BIDS-1582) replace old ad system with new generic ad configurations
  • Loading branch information
MauserBitfly authored Mar 13, 2023
1 parent 07197ba commit f0adf25
Show file tree
Hide file tree
Showing 89 changed files with 916 additions and 622 deletions.
3 changes: 3 additions & 0 deletions cmd/explorer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,9 @@ func main() {
authRouter.HandleFunc("/notifications/bundled/subscribe", handlers.MultipleUsersNotificationsSubscribeWeb).Methods("POST", "OPTIONS")
authRouter.HandleFunc("/global_notification", handlers.UserGlobalNotification).Methods("GET")
authRouter.HandleFunc("/global_notification", handlers.UserGlobalNotificationPost).Methods("POST")
authRouter.HandleFunc("/ad_configuration", handlers.AdConfiguration).Methods("GET")
authRouter.HandleFunc("/ad_configuration", handlers.AdConfigurationPost).Methods("POST")
authRouter.HandleFunc("/ad_configuration/delete", handlers.AdConfigurationDeletePost).Methods("POST")

authRouter.HandleFunc("/notifications-center", handlers.UserNotificationsCenter).Methods("GET")
authRouter.HandleFunc("/notifications-center/removeall", handlers.RemoveAllValidatorsAndUnsubscribe).Methods("POST")
Expand Down
141 changes: 141 additions & 0 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,147 @@ func GetMostRecentWithdrawalValidator() (uint64, error) {
return validatorindex, nil
}

// get all ad configurations
func GetAdConfigurations() ([]*types.AdConfig, error) {
var adConfigs []*types.AdConfig

err := ReaderDb.Select(&adConfigs, `
SELECT
id,
template_id,
jquery_selector,
insert_mode,
refresh_interval,
enabled,
for_all_users,
banner_id,
html_content
FROM
ad_configurations`)
if err != nil {
if err == sql.ErrNoRows {
return []*types.AdConfig{}, nil
}
return nil, fmt.Errorf("error getting ad configurations: %w", err)
}

return adConfigs, nil
}

// get the ad configuration for a specific template that are active
func GetAdConfigurationsForTemplate(ids []string, noAds bool) ([]*types.AdConfig, error) {
var adConfigs []*types.AdConfig
forAllUsers := ""
if noAds {
forAllUsers = " AND for_all_users = true"
}
err := ReaderDb.Select(&adConfigs, fmt.Sprintf(`
SELECT
id,
template_id,
jquery_selector,
insert_mode,
refresh_interval,
enabled,
for_all_users,
banner_id,
html_content
FROM
ad_configurations
WHERE
template_id = ANY($1) AND
enabled = true %v`, forAllUsers), pq.Array(ids))
if err != nil {
if err == sql.ErrNoRows {
return []*types.AdConfig{}, nil
}
return nil, fmt.Errorf("error getting ad configurations for template: %v %s", err, ids)
}

return adConfigs, nil
}

// insert new ad configuration
func InsertAdConfigurations(adConfig types.AdConfig) error {
_, err := WriterDb.Exec(`
INSERT INTO ad_configurations (
id,
template_id,
jquery_selector,
insert_mode,
refresh_interval,
enabled,
for_all_users,
banner_id,
html_content)
VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT DO NOTHING`,
adConfig.Id,
adConfig.TemplateId,
adConfig.JQuerySelector,
adConfig.InsertMode,
adConfig.RefreshInterval,
adConfig.Enabled,
adConfig.ForAllUsers,
adConfig.BannerId,
adConfig.HtmlContent)
if err != nil {
return fmt.Errorf("error inserting ad configuration: %w", err)
}
return nil
}

// update exisiting ad configuration
func UpdateAdConfiguration(adConfig types.AdConfig) error {
tx, err := WriterDb.Begin()
if err != nil {
return fmt.Errorf("error starting db transactions: %w", err)
}
defer tx.Rollback()
_, err = tx.Exec(`
UPDATE ad_configurations SET
template_id = $2,
jquery_selector = $3,
insert_mode = $4,
refresh_interval = $5,
enabled = $6,
for_all_users = $7,
banner_id = $8,
html_content = $9
WHERE id = $1;`,
adConfig.Id,
adConfig.TemplateId,
adConfig.JQuerySelector,
adConfig.InsertMode,
adConfig.RefreshInterval,
adConfig.Enabled,
adConfig.ForAllUsers,
adConfig.BannerId,
adConfig.HtmlContent)
if err != nil {
return fmt.Errorf("error updating ad configuration: %w", err)
}
return tx.Commit()
}

// delete ad configuration
func DeleteAdConfiguration(id string) error {

tx, err := WriterDb.Beginx()
if err != nil {
return fmt.Errorf("error starting db transactions: %w", err)
}
defer tx.Rollback()

// delete ad configuration
_, err = WriterDb.Exec(`
DELETE FROM ad_configurations
WHERE
id = $1;`,
id)
return err
}

func GetTotalBLSChanges() (uint64, error) {
var count uint64
err := ReaderDb.Get(&count, `
Expand Down
5 changes: 3 additions & 2 deletions handlers/404.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ func handleHTTPError(err error, handler func(http.ResponseWriter, *http.Request)
}

func NotFound(w http.ResponseWriter, r *http.Request) {
notFoundTemplate := templates.GetTemplate(append(layoutTemplateFiles, "svg/relax.html", "404notfound.html")...)
templateFiles := append(layoutTemplateFiles, "svg/relax.html", "404notfound.html")
notFoundTemplate := templates.GetTemplate(templateFiles...)

w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusNotFound)
data := InitPageData(w, r, "blockchain", r.URL.Path, "Not Found")
data := InitPageData(w, r, "blockchain", r.URL.Path, "Not Found", templateFiles)
err := notFoundTemplate.ExecuteTemplate(w, "layout", data)
if err != nil {
logger.Errorf("error executing not-found template for %v route: %v", r.URL.String(), err)
Expand Down
164 changes: 164 additions & 0 deletions handlers/ad_configuration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package handlers

import (
"eth2-exporter/db"
"eth2-exporter/templates"
"eth2-exporter/types"
"eth2-exporter/utils"
"net/http"
"strconv"

"github.com/google/uuid"
"github.com/gorilla/csrf"
)

// Load Ad Configuration page
func AdConfiguration(w http.ResponseWriter, r *http.Request) {
templateFiles := append(layoutTemplateFiles, "user/ad_configuration.html")
var userTemplate = templates.GetTemplate(templateFiles...)

w.Header().Set("Content-Type", "text/html")

if !hasPermission(w, r) {
return
}

configs, err := db.GetAdConfigurations()

if err != nil {
utils.LogError(err, "error loading the ad configuration", 0)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}

data := InitPageData(w, r, "user", "/user/ad_configuration", "Ad Configuration", templateFiles)
pageData := types.AdConfigurationPageData{}
pageData.CsrfField = csrf.TemplateField(r)
pageData.Configurations = configs
pageData.TemplateNames = templates.GetTemplateNames()
pageData.New = types.AdConfig{
InsertMode: "replace",
TemplateId: "index/index.html",
JQuerySelector: "#r-banner",
Enabled: true,
}
data.Data = pageData

if handleTemplateError(w, r, "ad_configuration.go", "AdConfiguration", "", userTemplate.ExecuteTemplate(w, "layout", data)) != nil {
return // an error has occurred and was processed
}
}

// Insert / Update Ad configuration
func AdConfigurationPost(w http.ResponseWriter, r *http.Request) {
if !hasPermission(w, r) {
return
}

err := r.ParseForm()
if err != nil {
utils.LogError(err, "error parsing form", 0)
http.Redirect(w, r, "/user/ad_configuration?error=parsingForm", http.StatusSeeOther)
return
}
id := r.FormValue(`id`)

refreshInterval, err := strconv.ParseUint(r.FormValue(`refreshInterval`), 0, 64)
if err != nil {
refreshInterval = 0
}

var bannerId uint64
var htmlContent = ""
if len(r.FormValue(`useHtmlContent`)) > 0 {
htmlContent = r.FormValue(`htmlContent`)

if len(htmlContent) == 0 {
utils.LogError(nil, "error with provided html content", 0)
http.Redirect(w, r, "/user/ad_configuration?error=noHtmlContent", http.StatusSeeOther)
return
}
} else {
bannerId, err = strconv.ParseUint(r.FormValue(`bannerId`), 0, 64)
if err != nil || bannerId == 0 {
utils.LogError(err, "error no bannerId provided", 0)
http.Redirect(w, r, "/user/ad_configuration?error=noBannerId", http.StatusSeeOther)
return
}
}

adConfig := types.AdConfig{
Id: id,
TemplateId: r.FormValue(`templateId`),
JQuerySelector: r.FormValue(`jQuerySelector`),
InsertMode: r.FormValue(`insertMode`),
RefreshInterval: refreshInterval,
Enabled: len(r.FormValue(`enabled`)) > 0,
ForAllUsers: len(r.FormValue(`forAllUsers`)) > 0,
BannerId: bannerId,
HtmlContent: htmlContent,
}

if len(adConfig.Id) == 0 {
adConfig.Id = uuid.New().String()
err = db.InsertAdConfigurations(adConfig)
if err != nil {
utils.LogError(err, "error inserting new ad config", 0)
http.Redirect(w, r, "/user/ad_configuration?error=insertingConfig", http.StatusSeeOther)
return
}

} else {
err = db.UpdateAdConfiguration(adConfig)
if err != nil {
utils.LogError(err, "error updating ad config", 0)
http.Redirect(w, r, "/user/ad_configuration?error=updatingConfig", http.StatusSeeOther)
return
}
}

http.Redirect(w, r, "/user/ad_configuration", http.StatusSeeOther)
}

// Delete Ad configuration
func AdConfigurationDeletePost(w http.ResponseWriter, r *http.Request) {
if !hasPermission(w, r) {
return
}
err := r.ParseForm()
if err != nil {
utils.LogError(err, "error parsing form", 0)
http.Redirect(w, r, "/user/ad_configuration?error=parsingForm", http.StatusSeeOther)
return
}
id := r.FormValue(`id`)
if len(id) == 0 {
utils.LogError(err, "error no id provided", 0)
http.Redirect(w, r, "/user/ad_configuration?error=noTemplateId", http.StatusSeeOther)
return
}

err = db.DeleteAdConfiguration(id)
if err != nil {
utils.LogError(err, "error deleting ad config", 0)
http.Redirect(w, r, "/user/ad_configuration?error=notDeleted", http.StatusSeeOther)
return
}

http.Redirect(w, r, "/user/ad_configuration", http.StatusSeeOther)
}

func hasPermission(w http.ResponseWriter, r *http.Request) bool {
user, _, err := getUserSession(r)
if err != nil {
utils.LogError(err, "error retrieving session", 0)
http.Error(w, "Internal server error", http.StatusInternalServerError)
return false
}

if user.UserGroup != "ADMIN" {
http.Error(w, "Insufficient privileges", http.StatusUnauthorized)
return false
}
return true
}
5 changes: 3 additions & 2 deletions handlers/advertisewithus.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import (
)

func AdvertiseWithUs(w http.ResponseWriter, r *http.Request) {
var advertisewithusTemplate = templates.GetTemplate(append(layoutTemplateFiles, "advertisewithus.html")...)
templateFiles := append(layoutTemplateFiles, "advertisewithus.html")
var advertisewithusTemplate = templates.GetTemplate(templateFiles...)

var err error

w.Header().Set("Content-Type", "text/html")

data := InitPageData(w, r, "advertisewithus", "/advertisewithus", "Adverstise With Us")
data := InitPageData(w, r, "advertisewithus", "/advertisewithus", "Adverstise With Us", templateFiles)

pageData := &types.AdvertiseWithUsPageData{}
pageData.RecaptchaKey = utils.Config.Frontend.RecaptchaSiteKey
Expand Down
Loading

0 comments on commit f0adf25

Please sign in to comment.