github.com/elliott5/community@v0.14.1-0.20160709191136-823126fb026a/documize/api/endpoint/sections_endpoint.go (about)

     1  // Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
     2  //
     3  // This software (Documize Community Edition) is licensed under
     4  // GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
     5  //
     6  // You can operate outside the AGPL restrictions by purchasing
     7  // Documize Enterprise Edition and obtaining a commercial license
     8  // by contacting <sales@documize.com>.
     9  //
    10  // https://documize.com
    11  
    12  package endpoint
    13  
    14  import (
    15  	"encoding/json"
    16  	"net/http"
    17  
    18  	"github.com/documize/community/documize/api/entity"
    19  	"github.com/documize/community/documize/api/request"
    20  	"github.com/documize/community/documize/api/util"
    21  	"github.com/documize/community/documize/section/provider"
    22  	"github.com/documize/community/wordsmith/log"
    23  )
    24  
    25  // GetSections returns available smart sections.
    26  func GetSections(w http.ResponseWriter, r *http.Request) {
    27  	method := "GetSections"
    28  
    29  	json, err := json.Marshal(provider.GetSectionMeta())
    30  
    31  	if err != nil {
    32  		writeJSONMarshalError(w, method, "section", err)
    33  		return
    34  	}
    35  
    36  	writeSuccessBytes(w, json)
    37  }
    38  
    39  // RunSectionCommand passes UI request to section handler.
    40  func RunSectionCommand(w http.ResponseWriter, r *http.Request) {
    41  	method := "WebCommand"
    42  	p := request.GetPersister(r)
    43  
    44  	query := r.URL.Query()
    45  	documentID := query.Get("documentID")
    46  	sectionName := query.Get("section")
    47  
    48  	// Missing value checks
    49  	if len(documentID) == 0 {
    50  		writeMissingDataError(w, method, "documentID")
    51  		return
    52  	}
    53  
    54  	if len(sectionName) == 0 {
    55  		writeMissingDataError(w, method, "section")
    56  		return
    57  	}
    58  
    59  	// Note that targetMethod query item can be empty --
    60  	// it's up to the section handler to parse if required.
    61  
    62  	// Permission checks
    63  	if !p.CanChangeDocument(documentID) {
    64  		writeForbiddenError(w)
    65  		return
    66  	}
    67  
    68  	if !p.Context.Editor {
    69  		writeForbiddenError(w)
    70  		return
    71  	}
    72  
    73  	if !provider.Command(sectionName, provider.NewContext(p.Context.OrgID, p.Context.UserID), w, r) {
    74  		log.ErrorString("Unable to run provider.Command() for: " + sectionName)
    75  		writeNotFoundError(w, "RunSectionCommand", sectionName)
    76  	}
    77  }
    78  
    79  // RefreshSections updates document sections where the data
    80  // is externally sourced.
    81  func RefreshSections(w http.ResponseWriter, r *http.Request) {
    82  	method := "RefreshSections"
    83  	p := request.GetPersister(r)
    84  
    85  	query := r.URL.Query()
    86  	documentID := query.Get("documentID")
    87  
    88  	if len(documentID) == 0 {
    89  		writeMissingDataError(w, method, "documentID")
    90  		return
    91  	}
    92  
    93  	if !p.CanViewDocument(documentID) {
    94  		writeForbiddenError(w)
    95  		return
    96  	}
    97  
    98  	// Return payload
    99  	var pages []entity.Page
   100  
   101  	// Let's see what sections are reliant on external sources
   102  	meta, err := p.GetDocumentPageMeta(documentID, true)
   103  
   104  	if err != nil {
   105  		writeGeneralSQLError(w, method, err)
   106  		return
   107  	}
   108  
   109  	tx, err := request.Db.Beginx()
   110  
   111  	if err != nil {
   112  		writeTransactionError(w, method, err)
   113  		return
   114  	}
   115  
   116  	p.Context.Transaction = tx
   117  
   118  	for _, pm := range meta {
   119  		// Grab the page because we need content type and
   120  		page, err2 := p.GetPage(pm.PageID)
   121  
   122  		if err2 != nil {
   123  			writeGeneralSQLError(w, method, err2)
   124  			log.IfErr(tx.Rollback())
   125  			return
   126  		}
   127  
   128  		pcontext := provider.NewContext(pm.OrgID, pm.UserID)
   129  
   130  		// Ask for data refresh
   131  		data, ok := provider.Refresh(page.ContentType, pcontext, pm.Config, pm.RawBody)
   132  		if !ok {
   133  			log.ErrorString("provider.Refresh could not find: " + page.ContentType)
   134  		}
   135  
   136  		// Render again
   137  		body, ok := provider.Render(page.ContentType, pcontext, pm.Config, data)
   138  		if !ok {
   139  			log.ErrorString("provider.Render could not find: " + page.ContentType)
   140  		}
   141  
   142  		// Compare to stored render
   143  		if body != page.Body {
   144  
   145  			// Persist latest data
   146  			page.Body = body
   147  			pages = append(pages, page)
   148  
   149  			refID := util.UniqueID()
   150  			err = p.UpdatePage(page, refID, p.Context.UserID, false)
   151  
   152  			if err != nil {
   153  				writeGeneralSQLError(w, method, err)
   154  				log.IfErr(tx.Rollback())
   155  				return
   156  			}
   157  
   158  			err = p.UpdatePageMeta(pm, false) // do not change the UserID on this PageMeta
   159  
   160  			if err != nil {
   161  				writeGeneralSQLError(w, method, err)
   162  				log.IfErr(tx.Rollback())
   163  				return
   164  			}
   165  		}
   166  	}
   167  
   168  	log.IfErr(tx.Commit())
   169  
   170  	json, err := json.Marshal(pages)
   171  
   172  	if err != nil {
   173  		writeJSONMarshalError(w, method, "pages", err)
   174  		return
   175  	}
   176  
   177  	writeSuccessBytes(w, json)
   178  }