Пример #1
0
func init() {
	var tokenFormValidator = v.NewFormValidator()
	tokenFormValidator.IntField("alert_on").Min(0)

	app.Api.Get("/api_tokens/", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			d := lib.NewApiTokenDriver(lib.NewAppContextFromRequest(req))
			tokens := make([]*models.ApiToken, 0)
			_, err := d.NewQuery().GetAll(&tokens)
			if err != nil {
				panic(err)
			}
			res.WriteJson(tokens)
		},
	))

	app.Api.Post("/api_tokens/", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			d := lib.NewApiTokenDriver(lib.NewAppContextFromRequest(req))
			t, err := d.Issue(req.Form("desc"))
			if err != nil {
				app.Api.InternalError(res, req, err)
			}
			app.Api.Created(res, req, t.Token)
		},
	))

	put_fn := lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			err := tokenFormValidator.Eval(req.HttpRequest().PostForm)
			if err != nil {
				app.Api.BadRequest(res, req, err)
				return
			}
			alertOn, _ := strconv.Atoi(req.Form("alert_on"))
			d := lib.NewApiTokenDriver(lib.NewAppContextFromRequest(req))
			err = d.Update(req.Param("token"), req.Form("desc"), time.Duration(alertOn))
			if err != nil {
				app.Api.InternalError(res, req, err)
			}
			app.Api.Ok(res, req)
		},
	)

	app.Api.Put("/api_tokens/:token/", put_fn) // TODO: remove this after client fixed.
	app.Api.Put("/api_tokens/:token.json", put_fn)

	delete_fn := lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			d := lib.NewApiTokenDriver(lib.NewAppContextFromRequest(req))
			err := d.Revoke(req.Param("token"))
			if err != nil {
				app.Api.InternalError(res, req, err)
			}
			app.Api.Ok(res, req)
		},
	)
	app.Api.Delete("/api_tokens/:token/", delete_fn) // TODO: remove this after client fixed.
	app.Api.Delete("/api_tokens/:token.json", delete_fn)
}
Пример #2
0
func setupYAuctionCron(app *App) {
	app.Cron.Get(
		"Crawl registered keywords and generate AuctionItem with Assoc.",
		"every 1 hours synchronized",
		"/yauction/keywords/",
		lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
			err := crawlKeywords(lib.NewAppContextFromRequest(req))
			if err != nil {
				lib.Error(res, req, err)
				return
			}
			app.Api.Ok(res, req)
		}),
	)

	app.Cron.Get(
		"Crawl expired AuctionItems to finalize properties.",
		"every 1 hours from 02:00 to 22:00",
		"/yauction/auctions/",
		lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
			err := crawlExpiredAuctions(lib.NewAppContextFromRequest(req))
			if err != nil {
				lib.Error(res, req, err)
				return
			}
			app.Api.Ok(res, req)
		}),
	)

	app.Cron.Get(
		"Crawl expired AuctionItems to finalize properties.",
		"every 10 minutes from 00:00 to 02:00",
		"/yauction/auctions/",
		lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
			err := crawlExpiredAuctions(lib.NewAppContextFromRequest(req))
			if err != nil {
				lib.Error(res, req, err)
				return
			}
			app.Api.Ok(res, req)
		}),
	)

	app.Cron.Get(
		"Crawl expired AuctionItems to finalize properties.",
		"every 10 minutes from 22:00 to 23:59",
		"/yauction/auctions/",
		lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
			err := crawlExpiredAuctions(lib.NewAppContextFromRequest(req))
			if err != nil {
				lib.Error(res, req, err)
				return
			}
			app.Api.Ok(res, req)
		}),
	)

}
Пример #3
0
func setupPages(app *App) {
	app.Page.Page("/insights/:member.html", "").
		AssetPath("/artistapp/insights.js").
		Templates("./artistapp/insights.html").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				member, ok := app.Members[req.Param("member")]
				if !ok {
					app.Page.NotFound(res, req)
					return
				}

				// load the recent post
				var list []*ameblo.AmebloEntry
				d := NewAmebloEntryDriver(lib.NewAppContextFromRequest(req))
				q := d.NewQuery().Filter("Owner =", member.Name).Order("-PostAt").Limit(1)
				if _, err := q.GetAll(&list); err != nil {
					app.Page.InternalError(res, req, err)
					return
				}
				if len(list) > 0 {
					list[0].Content, _ = list[0].GetDescription()
					res.SetLocal("RecentAmebloEntry", list[0])
				}

				p.Ogp("type", "website").
					Ogp("title", fmt.Sprintf("%s / %s", p.Title, p.App.Title)).
					Ogp("description", fmt.Sprintf("%sのSNSデータを可視化しています。", member.Name)).
					Ogp("image", member.PictureUrl)

				res.SetLocal("Member", member)
			})
}
Пример #4
0
func indexAllMembers(res *wcg.Response, req *wcg.Request, app *App) {
	var appCtx = lib.NewAppContextFromRequest(req)
	result := make(map[string][]string)
	crawler := ameblo.NewCrawler(appCtx.NewHttpClient())

	for _, m := range app.Members {
		req.Logger.Debug("Crawling %s (%s)", m.BlogUrl, m.Name)
		entries, err := crawler.CrawlEntryList(m.BlogUrl)
		if err != nil {
			req.Logger.Error("An error occurred while crawling %s: %v", m.BlogUrl, err)
			continue
		}
		req.Logger.Debug("Found %d entries.", len(entries))
		list := make([]string, 0)
		for _, e := range entries {
			e.Owner = m.Name
			list = append(list, e.Url)
		}
		if err := updateIndexes(appCtx, entries); err != nil {
			req.Logger.Error("Failed to update the entry: %v", err)
		} else {
			result[m.Name] = list
		}
	}

	// invalidate the cache
	time.Sleep(10 * time.Second) // TODO: wait for all indexes are updated on datastore.
	mc := appCtx.NewMemcacheDriver()
	for _, m := range app.Members {
		mckey := fmt.Sprintf(MC_KEY_HISTORY, app.Key, m.Name)
		mc.Delete(mckey)
	}
	res.WriteJson(result)
}
Пример #5
0
func queryShows(res *wcg.Response, req *wcg.Request, q *datastore.Query) (*showQueryResult, error) {
	var appCtx = lib.NewAppContextFromRequest(req)
	var showList []event.Show
	var basePath = req.HttpRequest().URL.Path
	per_page := 12 // Restict to 12 due to view rendering.
	page := wcg.ParseInt(req.Query("page"), 0, 0, wcg.ParseIntMax)
	if _, err := q.Offset(page * per_page).Limit(per_page).GetAll(&showList); err != nil {
		return nil, err
	}
	if showList == nil {
		return &showQueryResult{
			Shows: make([]EventShow, 0),
		}, nil
	}

	if list, err := NewEventShowList(appCtx, showList); err != nil {
		return nil, err
	} else {
		p := &showQueryResult{
			Shows:   list,
			Current: fmt.Sprintf("%s?page=%d&n=%d", basePath, page, per_page),
		}

		// prev url
		if page > 0 {
			p.Previous = fmt.Sprintf("%s?page=%d&n=%d", basePath, page-1, per_page)
		}

		// next url
		if len(p.Shows) == per_page {
			p.Next = fmt.Sprintf("%s?page=%d&n=%d", basePath, page+1, per_page)
		}
		return p, nil
	}
}
Пример #6
0
func loadEvent(app *App, req *wcg.Request, key string) (*event.Event, error) {
	var e event.Event
	d := NewEventDriver(lib.NewAppContextFromRequest(req))
	if err := d.Get(d.NewKey(req.Param(key), 0, nil), &e); err != nil {
		return nil, err
	} else {
		return &e, nil
	}
}
Пример #7
0
func indexSpecifiedMember(res *wcg.Response, req *wcg.Request, app *App) {
	var appCtx = lib.NewAppContextFromRequest(req)
	member, ok := app.Members[req.Param("member")]
	if !ok {
		lib.NotFound(res, req)
		return
	}

	num := wcg.ParseInt(req.Param("n"), 0, 0, wcg.ParseIntMax)
	if num == 0 {
		num = wcg.ParseIntMax
	}
	// Crawling
	crawler := ameblo.NewCrawler(appCtx.NewHttpClient())
	prefix := strings.TrimSuffix(member.BlogUrl, ".html") // xxxx.html => xxxx-{num}.html
	entries := make([]*ameblo.AmebloEntry, 0)
	for i := 1; i < num; i += 1 {
		url := fmt.Sprintf("%s-%d.html", prefix, i)
		req.Logger.Info("Indexing from %s ... ", url)
		newentries, err := crawler.CrawlEntryList(url)
		if err != nil {
			lib.InternalError(res, req, err)
			return
		}
		if len(newentries) > 20 {
			panic(fmt.Errorf("Unexpected number of entries (%d) are returned during indexing.", len(newentries)))
		}
		if len(newentries) == 0 {
			break
		}
		if len(newentries) < 20 {
			entries = append(entries, newentries...)
			break
		}
		if len(entries) > 0 && entries[len(entries)-1].Url == newentries[len(newentries)-1].Url {
			break
		}
		entries = append(entries, newentries...)
	}

	// Save and return resutls
	results := make([]string, 0)
	for _, ent := range entries {
		ent.Owner = member.Name
		results = append(results, ent.Url)
	}
	if err := updateIndexes(appCtx, entries); err != nil {
		req.Logger.Error("Failed to update the entry: %v", err)
		lib.InternalError(res, req, err) // stopped.
	} else {
		time.Sleep(10 * time.Second) // TODO: wait for all indexes are updated on datastore.
		mc := appCtx.NewMemcacheDriver()
		mckey := fmt.Sprintf(MC_KEY_HISTORY, app.Key, member.Name)
		mc.Delete(mckey)
		res.WriteJson(results)
	}
}
Пример #8
0
func setupApi(app *App) {
	app.Api.Get("/ameblo/insights/:member/history.json", func(res *wcg.Response, req *wcg.Request) {
		historyInsights(res, req, app)
	})
	app.Api.Get("/ameblo/indexes/", lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
		indexAllMembers(res, req, app)
	}))
	app.Api.Get("/ameblo/indexes/:member.json", lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
		indexSpecifiedMember(res, req, app)
	}))
	app.Api.Get("/ameblo/contents/", lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
		crawlAllMembers(res, req, app)
	}))
	app.Api.Get("/ameblo/contents/:member.json", lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
		crawlSpecifiedMembers(res, req, app)
	}))
	app.Api.Delete("/ameblo/contents/:member.json", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			var appCtx = lib.NewAppContextFromRequest(req)

			member, ok := app.Members[req.Param("member")]
			if !ok {
				lib.NotFound(res, req)
				return
			}

			PER_ENT := 100
			offset := 0
			d := NewAmebloEntryDriver(appCtx)

			for {
				var list []*ameblo.AmebloEntry
				var q = d.NewQuery().Filter("Owner =", member.Name).Offset(offset).Limit(PER_ENT)
				if keys, err := q.GetAll(&list); err != nil {
					lib.InternalError(res, req, err)
					return
				} else {
					for _, ent := range list {
						ent.CrawledAt = time.Time{}
					}
					if _, err = d.PutMulti(keys, list); datastore.IsDatastoreError(err) {
						lib.InternalError(res, req, err)
					}
					offset = offset + len(list)
					if len(list) < PER_ENT {
						break
					}
				}
			}
			app.Api.Ok(res, req)
		},
	))
}
Пример #9
0
func setupPages(app *App) {
	app.Page.Navi("/", "記事一覧").
		AssetPath("/blogapp/index.js").
		Templates("./blogapp/list.html", "./blogapp/post_part.html").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				result, err := queryPosts(res, req, 20)
				if err != nil {
					panic(err)
				}
				p.Ogp("type", "blog")
				res.SetLocal("Posts", result.Posts)
				res.SetLocal("Next", result.Next)
				res.SetLocal("Previous", result.Previous)
			},
		)

	app.Page.Navi("/admin/editor.html", "記事管理").
		RequireAuth(lib.Admin).
		Templates("./blogapp/admin/editor.html").
		AssetPath("/blogapp/admin/editor.js")

	app.Page.Page("/posts/:id.html", "").
		Templates("./blogapp/show.html", "./blogapp/post_part.html").
		AssetPath("/blogapp/posts/show.js").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				var post blog.Post
				driver := NewPostDriver(lib.NewAppContextFromRequest(req))
				key := driver.NewKey(req.Param("id"), 0, nil)
				err := driver.Get(key, &post)
				if err != nil {
					lib.Error(res, req, err)
					return
				}
				p.Title = post.Title
				p.Canonical = wcg.AbsoluteUrl(req, app.Page.Path(fmt.Sprintf("/posts/%s.html", post.Id)))
				p.Ogp("title", fmt.Sprintf("%s: %s", p.App.Title, p.Title))
				p.Ogp("url", p.Canonical)
				p.Ogp("type", "article")
				p.Ogp("description", post.Summary())
				imageUrl := post.ExtractFirstImageUrl()
				if imageUrl != "" {
					p.Ogp("image", imageUrl)
				}
				res.SetLocal("Post", post)
			})
}
Пример #10
0
func setupEventCron(app *App) {
	app.Cron.Get(
		"Generate YAKeyword crawling metadata for registered event show entries.",
		"every 1 hours synchronized",
		"/event/yakeywords/",
		lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
			updateKeys, err := generateYACrawlerKeywords(lib.NewAppContextFromRequest(req))
			if err != nil {
				lib.Error(res, req, err)
				return
			}
			req.Logger.Info("Updating %d yauction keyword entries from event.", len(updateKeys))
			app.Api.Ok(res, req)
		}),
	)
}
Пример #11
0
func init() {
	app.Cron.Get(
		"Monitor API tokens",
		"every 1 minutes",
		"/api_tokens/",
		lib.Admin.Required(
			func(res *wcg.Response, req *wcg.Request) {
				var tokens []*models.ApiToken
				d := lib.NewApiTokenDriver(lib.NewAppContextFromRequest(req))
				_, err := d.NewQuery().GetAll(&tokens)
				if err != nil {
					panic(err)
				}

				m := 0
				c := 0
				for _, t := range tokens {
					if t.AlertOn > 0 {
						m += 1
						if t.ShouldAlert() {
							c += 1
							req.Logger.Fatal(
								"API Token '%s' losts access. The last access time was %s (Threshould: %d minutes).",
								t.Token,
								t.LastAccess,
								t.AlertOn,
							)
						}
					}
				}
				if c > 0 {
					notifications.SendAlert(
						req,
						"API token(s) have not been accessed for a while.",
						fmt.Sprintf(TMPL_ALERT_BODY, c, wcg.AbsoluteUrl(req, "/admin/clients.html")),
					)
				}
				res.WriteJson(map[string]interface{}{
					"alerted_tokens":   c,
					"monitored_tokens": m,
					"total_tokens":     len(tokens),
				})
			},
		))
}
Пример #12
0
func crawl(res *wcg.Response, req *wcg.Request, member *ameblo.Member, app *App) {
	var appCtx = lib.NewAppContextFromRequest(req)
	var logger = appCtx.Logger
	var targets []*ameblo.AmebloEntry
	result := make([]string, 0)

	d := NewAmebloEntryDriver(appCtx)
	crawler := ameblo.NewCrawler(appCtx.NewHttpClient())

	// prioritize the entries which are not crawled and are posted recently.
	q := d.NewQuery().Filter("CrawledAt =", time.Time{}).Order("PostAt").Limit(NUM_ENTRIES_TO_CRAWL_PER_CALL)
	if member != nil {
		q = q.Filter("Owner =", member.Name)
	}

	if _, err := q.GetAll(&targets); err != nil {
		lib.InternalError(res, req, err)
		return
	}

	// Crawl Contents
	for _, e := range targets {
		logger.Info("Crawling %s ... ", e.Url)
		if e1, err := crawler.CrawlEntry(e.Url); err != nil {
			logger.Warn("Failed to crawl %s, skipped: %v", e.Url, err)
			continue
		} else {
			if e1 == nil {
				logger.Warn("CrawlEntry returns nil entry for %s", e.Url)
				e.Content = "<No Content>"
				e.CrawledAt = time.Now()
			} else {
				logger.Debug("CrawlEntry scraped %d bytes.", len(e1.Content))
				e.Content = e1.Content
			}
			result = append(result, e.Url)
		}
	}
	if err := updateContents(appCtx, targets, app.MemberList); err != nil {
		lib.InternalError(res, req, err)
		return
	}
	res.WriteJson(result)
}
Пример #13
0
func queryPosts(res *wcg.Response, req *wcg.Request, per_page int) (*postQueryResult, error) {
	var list []blog.Post
	var basePath = req.HttpRequest().URL.Path
	is_admin := (lib.GetUserKind(req) == lib.Admin) && (req.Query("is_admin") == "true")
	if per_page == 0 {
		per_page = wcg.ParseInt(req.Query("n"), 5, 0, 20) // default 5, max 20
	}
	page := wcg.ParseInt(req.Query("page"), 0, 0, wcg.ParseIntMax)
	q := NewPostDriver(lib.NewAppContextFromRequest(req)).NewQuery()
	q = q.Order("-PublishAt").Order("-CreatedAt")
	if !is_admin {
		q = q.Filter("PublishAt <=", time.Now()).Filter("IsDraft =", false).Filter("IsHidden =", false)
	}

	_, err := q.Offset(page * per_page).Limit(per_page).GetAll(&list)
	if err != nil {
		return nil, err
	}
	if list == nil {
		list = make([]blog.Post, 0)
	}

	p := &postQueryResult{
		Posts: list,
	}

	// prev url
	if page > 0 {
		p.Previous = fmt.Sprintf("%s?page=%d&n=%d", basePath, page-1, per_page)
		if is_admin {
			p.Previous = fmt.Sprintf("%s&is_admin=true", p.Previous)
		}
	}

	// next url
	if len(list) == per_page {
		p.Next = fmt.Sprintf("%s?page=%d&n=%d", basePath, page+1, per_page)
		if is_admin {
			p.Next = fmt.Sprintf("%s&is_admin=true", p.Next)
		}
	}
	return p, nil
}
Пример #14
0
func historyInsights(res *wcg.Response, req *wcg.Request, app *App) {
	var appCtx = lib.NewAppContextFromRequest(req)
	member, ok := app.Members[req.Param("member")]
	if !ok {
		lib.NotFound(res, req)
		return
	}
	var insights amebloHistoryInsights
	mckey := fmt.Sprintf(MC_KEY_HISTORY, app.Key, member.Name)
	dent := NewAmebloEntryDriver(appCtx)
	dref := NewAmebloRefDriver(appCtx)
	mc := appCtx.NewMemcacheDriver()
	err := mc.CachedObject(mckey, &insights, func() (interface{}, error) {
		return getAmebloHistoryInsights(member, dent, dref)
	}, req.Query("force") == "1")
	if err != nil {
		lib.Error(res, req, err)
		return
	}
	res.WriteJson(insights)
}
Пример #15
0
func setupYAuctionPages(app *App) {
	app.Page.Page("/yauction/keywords/", "オークション状況").
		AssetPath("/artistapp/yauction/keyword.js").
		Templates("./artistapp/yauction/keyword.html").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				keyword := req.Query("q")
				var ckeyword yauction.CrawlerKeyword
				ckdriver := NewCrawlerKeywordDriver(lib.NewAppContextFromRequest(req))
				if err := ckdriver.Get(ckdriver.NewKey(keyword, 0, nil), &ckeyword); err != nil {
					if err == ds.ErrNoSuchEntity {
						app.Page.NotFound(res, req)
					} else {
						app.Page.InternalError(res, req, err)
					}
					return
				}
				p.Title = fmt.Sprintf("ヤフオク: %q", keyword)
				p.Ogp("title", fmt.Sprintf("ヤフオク: %q", keyword))
				res.SetLocal("Keyword", keyword)
			})
}
Пример #16
0
func setupYAuctionApi(app *App) {
	app.Api.Get("/yauction/admin/closed/", lib.Admin.Required(func(res *wcg.Response, req *wcg.Request) {
		var appCtx = lib.NewAppContextFromRequest(req)
		keyword := req.Query("q")
		if keyword == "" {
			app.Api.BadRequest(res, req, fmt.Errorf("Missing 'q' parameter."))
			return
		}
		ids, err := crawlClosedKeyword(appCtx, keyword)
		if err != nil && ids == nil {
			lib.Error(res, req, err)
			return
		}
		if err != nil {
			res.WriteJson(map[string]interface{}{
				"num_updates": len(ids),
				"auction_ids": ids,
				"error":       err.Error(),
			})
		} else {
			res.WriteJson(map[string]interface{}{
				"num_updates": len(ids),
				"auction_ids": ids,
			})
		}
	}))

	app.Api.Get("/yauction/keywords/", func(res *wcg.Response, req *wcg.Request) {
		keyword, _ := url.QueryUnescape(req.Query("q"))
		var appCtx = lib.NewAppContextFromRequest(req)
		var ckeyword yauction.CrawlerKeyword
		var assocs []yauction.AssocCrawlerKeywordAuctionItem

		ckdriver := NewCrawlerKeywordDriver(appCtx)
		assocdriver := NewAssocCrawlerKeywordAuctionItemDriver(appCtx)
		aidriver := NewAuctionItemDriver(appCtx)

		if err := ckdriver.Get(ckdriver.NewKey(keyword, 0, nil), &ckeyword); err != nil {
			if err == ds.ErrNoSuchEntity {
				app.Api.NotFound(res, req)
			} else {
				app.Api.InternalError(res, req, err)
			}
			return
		}

		if _, err := assocdriver.NewQuery().Filter("Keyword =", keyword).GetAll(&assocs); err != nil {
			app.Api.InternalError(res, req, err)
			return
		}

		itemKeys := make([]*datastore.Key, len(assocs))
		items := make([]yauction.AuctionItem, len(assocs))
		for i, assoc := range assocs {
			itemKeys[i] = aidriver.NewKey(assoc.AuctionId, 0, nil)
		}

		err := aidriver.GetMulti(itemKeys, items)
		if ds.IsDatastoreError(err) {
			app.Api.InternalError(res, req, err)
			return
		}

		res.WriteJson(map[string]interface{}{
			"keyword":  ckeyword,
			"auctions": items,
		})
	})
}
Пример #17
0
func setupApi(app *App) {
	app.Api.Get("/posts/", func(res *wcg.Response, req *wcg.Request) {
		if result, err := queryPosts(res, req, 0); err != nil {
			lib.Error(res, req, err)
		} else {
			res.WriteJson(result)
		}
	})

	app.Api.Get("/posts/:id.json", func(res *wcg.Response, req *wcg.Request) {
		var p blog.Post
		driver := NewPostDriver(lib.NewAppContextFromRequest(req))
		key := driver.NewKey(req.Param("id"), 0, nil)
		if err := driver.Get(key, &p); err != nil {
			lib.Error(res, req, err)
			return
		}
		if p.IsDraft && lib.GetUserKind(req) != lib.Admin {
			app.Api.NotFound(res, req)
		} else {
			res.WriteJson(p)
		}
	})

	app.Api.Post("/posts/", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			driver := NewPostDriver(lib.NewAppContextFromRequest(req))
			p := &blog.Post{}
			if err := updateAttributesFromForm(res, req, p); err != nil {
				lib.Error(res, req, err)
				return
			}
			if _, err := driver.Save(p); err != nil {
				lib.Error(res, req, err)
			}
			app.Api.Created(res, req, p.Id)
		},
	))

	app.Api.Put("/posts/:id.json", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			var p blog.Post
			driver := NewPostDriver(lib.NewAppContextFromRequest(req))
			key := driver.NewKey(req.Param("id"), 0, nil)
			if err := driver.Get(key, &p); err != nil {
				lib.Error(res, req, err)
				return
			}
			if err := updateAttributesFromForm(res, req, &p); err != nil {
				lib.Error(res, req, err)
				return
			}
			if _, err := driver.Save(&p); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				app.Api.Ok(res, req)
			}
		},
	))

	app.Api.Delete("/posts/:id.json", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			driver := NewPostDriver(lib.NewAppContextFromRequest(req))
			key := driver.NewKey(req.Param("id"), 0, nil)
			if err := driver.Delete(key); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				app.Api.Ok(res, req)
			}
		},
	))
}
Пример #18
0
func setupEventApi(app *App) {
	app.Api.Get("/events/", func(res *wcg.Response, req *wcg.Request) {
		var events []event.Event
		d := NewEventDriver(lib.NewAppContextFromRequest(req))
		if _, err := d.NewQuery().GetAll(&events); err != nil {
			lib.Error(res, req, err)
		} else {
			if events == nil {
				events = make([]event.Event, 0)
			}
			res.WriteJson(events)
		}
	})

	app.Api.Get("/events/importer/", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			var appCtx = lib.NewAppContextFromRequest(req)
			url := req.Query("url")
			if eventShowList, err := importer.Import(url, appCtx.NewHttpClient()); err != nil {
				lib.Error(res, req, err)
			} else {
				res.WriteJson(eventShowList)
			}
		},
	))

	app.Api.Post("/events/", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			t := &event.Event{}
			d := NewEventDriver(lib.NewAppContextFromRequest(req))
			if err := updateAttributesFromForm(res, req, t); err != nil {
				lib.Error(res, req, err)
				return
			}
			if t, err := d.Save(t); err != nil {
				lib.Error(res, req, err)
			} else {
				app.Api.Created(res, req, t.Id)
			}
		},
	))

	app.Api.Put("/events/:id.json", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			if t, err := loadEvent(app, req, "id"); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				if err := updateAttributesFromForm(res, req, t); err != nil {
					lib.Error(res, req, err)
					return
				}
				d := NewEventDriver(lib.NewAppContextFromRequest(req))
				if _, err := d.Save(t); err != nil {
					lib.Error(res, req, err)
				} else {
					app.Api.Ok(res, req)
				}
			}
		},
	))

	app.Api.Delete("/events/:id.json", lib.Admin.Required(
		func(res *wcg.Response, req *wcg.Request) {
			d := NewEventDriver(lib.NewAppContextFromRequest(req))
			if err := d.Delete(req.Param("id")); err != nil {
				lib.Error(res, req, err)
			} else {
				app.Api.Ok(res, req)
			}
		},
	))
}
Пример #19
0
func setupEventPages(app *App) {
	app.Page.Navi("/events/", "イベント").
		Templates("./artistapp/events.html", "./artistapp/show_part.html").
		AssetPath("/artistapp/events.js").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				var appCtx = lib.NewAppContextFromRequest(req)
				var all = req.Query("all") == "1"
				q := NewShowDriver(appCtx).NewQuery()
				if all {
					q = q.Order("-StartAt")
				} else {
					q = q.Filter("StartAt >=", util.Date(now())).Order("StartAt")
				}
				if result, err := queryShows(res, req, q); err != nil {
					lib.Error(res, req, err)
					return
				} else {
					p.Ogp("type", "blog")
					res.SetLocal("Shows", result.Shows)
					if all {
						res.SetLocal("Future", result.Current)
						res.SetLocal("Next", fmt.Sprintf("%s&all=1", result.Next))
						res.SetLocal("Previous", fmt.Sprintf("%s&all=1", result.Previous))
					} else {
						res.SetLocal("All", fmt.Sprintf("%s&all=1", result.Current))
						res.SetLocal("Next", result.Next)
						res.SetLocal("Previous", result.Previous)
					}
				}
			})

	app.Page.Page("/events/:name.html", "イベント").
		Templates("./artistapp/events.html").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				//d := NewShowDriver(app.Key, gae.NewContext(req), req.Logger)
			})

	app.Page.Navi("/admin/events.html", "イベント管理").
		Templates("./artistapp/admin/events.html").
		AssetPath("/artistapp/admin/events.js").
		RequireAuth(lib.Admin)

	app.Page.Page("/admin/events/:id.html", "").
		Templates("./artistapp/admin/events.html").
		AssetPath("/artistapp/admin/shows.js").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				var e event.Event
				d := NewEventDriver(lib.NewAppContextFromRequest(req))
				key := d.NewKey(req.Param("id"), 0, nil)
				if err := d.Get(key, &e); err != nil {
					lib.Error(res, req, err)
					return
				}
				p.Title = fmt.Sprintf("公演一覧 - %s", e.Title)
			})

	app.Page.Page("/venues/:id/", "").
		AssetPath("/artistapp/venues.js").
		Templates("./artistapp/venues.html").
		Handler(
			func(res *wcg.Response, req *wcg.Request, p *lib.Page) {
				var appCtx = lib.NewAppContextFromRequest(req)
				var showList []event.Show
				q := NewShowDriver(appCtx).NewQuery()
				q = q.Filter("VenueId =", req.Param("id"))
				if _, err := q.Limit(1).GetAll(&showList); err != nil {
					lib.Error(res, req, err)
					return
				}
				if len(showList) == 0 {
					app.Page.NotFound(res, req)
					return
				}
				if list, err := NewEventShowList(appCtx, showList); err != nil {
					lib.Error(res, req, err)
					return
				} else {
					ev := list[0]
					p.Title = fmt.Sprintf("会場情報 - %s", ev.VenueName)
					res.SetLocal("VenueName", ev.VenueName)
					res.SetLocal("Latitude", ev.Latitude)
					res.SetLocal("Longitude", ev.Longitude)
				}
			})

}
Пример #20
0
func setupEventShowApi(app *App) {
	app.Api.Get("/events/:event_id/shows/", func(res *wcg.Response, req *wcg.Request) {
		if e, err := loadEvent(app, req, "event_id"); err != nil {
			lib.Error(res, req, err)
			return
		} else {
			var list []event.Show
			d := NewShowDriver(lib.NewAppContextFromRequest(req))
			if _, err = d.NewQueryWithEventId(e.Id).GetAll(&list); err != nil {
				lib.Error(res, req, err)
				return
			}
			if list == nil {
				list = make([]event.Show, 0)
			}
			if req.Query("composit") == "1" {
				res.WriteJson(compositShowList{
					Event:    e,
					ShowList: list,
				})
			} else {
				res.WriteJson(list)
			}
		}
	})

	app.Api.Post("/events/:event_id/shows/", func(res *wcg.Response, req *wcg.Request) {
		if e, err := loadEvent(app, req, "event_id"); err != nil {
			lib.Error(res, req, err)
			return
		} else {
			if err := showFormValidator.Eval(req.HttpRequest().PostForm); err != nil {
				lib.Error(res, req, err)
				return
			}
			d := NewShowDriver(lib.NewAppContextFromRequest(req))
			s := updateShowAttributes(req, &event.Show{
				EventId: e.Id,
			})
			if s, err := d.Save(s); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				app.Api.Created(res, req, s.Id)
			}
		}
	})

	app.Api.Put("/events/:event_id/shows/:id.json", func(res *wcg.Response, req *wcg.Request) {
		if _, err := loadEvent(app, req, "event_id"); err != nil {
			lib.Error(res, req, err)
			return
		} else {
			var show event.Show
			d := NewShowDriver(lib.NewAppContextFromRequest(req))
			if _, err := d.Load(req.Param("id"), req.Param("event_id"), &show); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				if _, err = d.Save(updateShowAttributes(req, &show)); err != nil {
					lib.Error(res, req, err)
					return
				}
				res.WriteJson(show)
			}
		}
	})

	app.Api.Delete("/events/:event_id/shows/:id.json", func(res *wcg.Response, req *wcg.Request) {
		if e, err := loadEvent(app, req, "event_id"); err != nil {
			lib.Error(res, req, err)
			return
		} else {
			d := NewShowDriver(lib.NewAppContextFromRequest(req))
			if err := d.Delete(req.Param("id"), e.Id); err != nil {
				lib.Error(res, req, err)
				return
			} else {
				app.Api.Ok(res, req)
			}
		}
	})
}