Add new fields for feed username/password
This commit is contained in:
parent
261695c14c
commit
bddca15b69
27 changed files with 203 additions and 68 deletions
19
api/feed.go
19
api/feed.go
|
@ -15,18 +15,18 @@ import (
|
||||||
|
|
||||||
// CreateFeed is the API handler to create a new feed.
|
// CreateFeed is the API handler to create a new feed.
|
||||||
func (c *Controller) CreateFeed(w http.ResponseWriter, r *http.Request) {
|
func (c *Controller) CreateFeed(w http.ResponseWriter, r *http.Request) {
|
||||||
feedURL, categoryID, err := decodeFeedCreationPayload(r.Body)
|
feedInfo, err := decodeFeedCreationPayload(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.BadRequest(w, err)
|
json.BadRequest(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if feedURL == "" {
|
if feedInfo.FeedURL == "" {
|
||||||
json.BadRequest(w, errors.New("The feed_url is required"))
|
json.BadRequest(w, errors.New("The feed_url is required"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if categoryID <= 0 {
|
if feedInfo.CategoryID <= 0 {
|
||||||
json.BadRequest(w, errors.New("The category_id is required"))
|
json.BadRequest(w, errors.New("The category_id is required"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -34,17 +34,24 @@ func (c *Controller) CreateFeed(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := context.New(r)
|
ctx := context.New(r)
|
||||||
userID := ctx.UserID()
|
userID := ctx.UserID()
|
||||||
|
|
||||||
if c.store.FeedURLExists(userID, feedURL) {
|
if c.store.FeedURLExists(userID, feedInfo.FeedURL) {
|
||||||
json.BadRequest(w, errors.New("This feed_url already exists"))
|
json.BadRequest(w, errors.New("This feed_url already exists"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.store.CategoryExists(userID, categoryID) {
|
if !c.store.CategoryExists(userID, feedInfo.CategoryID) {
|
||||||
json.BadRequest(w, errors.New("This category_id doesn't exists or doesn't belongs to this user"))
|
json.BadRequest(w, errors.New("This category_id doesn't exists or doesn't belongs to this user"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
feed, err := c.feedHandler.CreateFeed(userID, categoryID, feedURL, false)
|
feed, err := c.feedHandler.CreateFeed(
|
||||||
|
userID,
|
||||||
|
feedInfo.CategoryID,
|
||||||
|
feedInfo.FeedURL,
|
||||||
|
feedInfo.Crawler,
|
||||||
|
feedInfo.Username,
|
||||||
|
feedInfo.Password,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.ServerError(w, errors.New("Unable to create this feed"))
|
json.ServerError(w, errors.New("Unable to create this feed"))
|
||||||
return
|
return
|
||||||
|
|
|
@ -23,6 +23,20 @@ type entriesResponse struct {
|
||||||
Entries model.Entries `json:"entries"`
|
Entries model.Entries `json:"entries"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type feedCreation struct {
|
||||||
|
FeedURL string `json:"feed_url"`
|
||||||
|
CategoryID int64 `json:"category_id"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Crawler bool `json:"crawler"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type subscriptionDiscovery struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
func decodeUserPayload(r io.ReadCloser) (*model.User, error) {
|
func decodeUserPayload(r io.ReadCloser) (*model.User, error) {
|
||||||
var user model.User
|
var user model.User
|
||||||
|
|
||||||
|
@ -35,19 +49,16 @@ func decodeUserPayload(r io.ReadCloser) (*model.User, error) {
|
||||||
return &user, nil
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeURLPayload(r io.ReadCloser) (string, error) {
|
func decodeURLPayload(r io.ReadCloser) (*subscriptionDiscovery, error) {
|
||||||
type payload struct {
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var p payload
|
|
||||||
decoder := json.NewDecoder(r)
|
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
if err := decoder.Decode(&p); err != nil {
|
|
||||||
return "", fmt.Errorf("invalid JSON payload: %v", err)
|
var s subscriptionDiscovery
|
||||||
|
decoder := json.NewDecoder(r)
|
||||||
|
if err := decoder.Decode(&s); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid JSON payload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.URL, nil
|
return &s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeEntryStatusPayload(r io.ReadCloser) ([]int64, string, error) {
|
func decodeEntryStatusPayload(r io.ReadCloser) ([]int64, string, error) {
|
||||||
|
@ -66,20 +77,16 @@ func decodeEntryStatusPayload(r io.ReadCloser) ([]int64, string, error) {
|
||||||
return p.EntryIDs, p.Status, nil
|
return p.EntryIDs, p.Status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeFeedCreationPayload(r io.ReadCloser) (string, int64, error) {
|
func decodeFeedCreationPayload(r io.ReadCloser) (*feedCreation, error) {
|
||||||
type payload struct {
|
|
||||||
FeedURL string `json:"feed_url"`
|
|
||||||
CategoryID int64 `json:"category_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var p payload
|
|
||||||
decoder := json.NewDecoder(r)
|
|
||||||
defer r.Close()
|
defer r.Close()
|
||||||
if err := decoder.Decode(&p); err != nil {
|
|
||||||
return "", 0, fmt.Errorf("invalid JSON payload: %v", err)
|
var fc feedCreation
|
||||||
|
decoder := json.NewDecoder(r)
|
||||||
|
if err := decoder.Decode(&fc); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid JSON payload: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.FeedURL, p.CategoryID, nil
|
return &fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeFeedModificationPayload(r io.ReadCloser) (*model.Feed, error) {
|
func decodeFeedModificationPayload(r io.ReadCloser) (*model.Feed, error) {
|
||||||
|
|
|
@ -15,13 +15,17 @@ import (
|
||||||
|
|
||||||
// GetSubscriptions is the API handler to find subscriptions.
|
// GetSubscriptions is the API handler to find subscriptions.
|
||||||
func (c *Controller) GetSubscriptions(w http.ResponseWriter, r *http.Request) {
|
func (c *Controller) GetSubscriptions(w http.ResponseWriter, r *http.Request) {
|
||||||
websiteURL, err := decodeURLPayload(r.Body)
|
subscriptionInfo, err := decodeURLPayload(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.BadRequest(w, err)
|
json.BadRequest(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions, err := subscription.FindSubscriptions(websiteURL)
|
subscriptions, err := subscription.FindSubscriptions(
|
||||||
|
subscriptionInfo.URL,
|
||||||
|
subscriptionInfo.Username,
|
||||||
|
subscriptionInfo.Password,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.ServerError(w, errors.New("Unable to discover subscriptions"))
|
json.ServerError(w, errors.New("Unable to discover subscriptions"))
|
||||||
return
|
return
|
||||||
|
|
|
@ -52,8 +52,10 @@ type Client struct {
|
||||||
|
|
||||||
// WithCredentials defines the username/password for HTTP Basic authentication.
|
// WithCredentials defines the username/password for HTTP Basic authentication.
|
||||||
func (c *Client) WithCredentials(username, password string) *Client {
|
func (c *Client) WithCredentials(username, password string) *Client {
|
||||||
|
if username != "" && password != "" {
|
||||||
c.username = username
|
c.username = username
|
||||||
c.password = password
|
c.password = password
|
||||||
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +161,7 @@ func (c *Client) executeRequest(request *http.Request) (*Response, error) {
|
||||||
ContentLength: resp.ContentLength,
|
ContentLength: resp.ContentLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug("[HttpClient:%s] URL=%s, EffectiveURL=%s, Code=%d, Length=%d, Type=%s, ETag=%s, LastMod=%s, Expires=%s",
|
logger.Debug("[HttpClient:%s] URL=%s, EffectiveURL=%s, Code=%d, Length=%d, Type=%s, ETag=%s, LastMod=%s, Expires=%s, Auth=%v",
|
||||||
request.Method,
|
request.Method,
|
||||||
c.url,
|
c.url,
|
||||||
response.EffectiveURL,
|
response.EffectiveURL,
|
||||||
|
@ -169,6 +171,7 @@ func (c *Client) executeRequest(request *http.Request) (*Response, error) {
|
||||||
response.ETag,
|
response.ETag,
|
||||||
response.LastModified,
|
response.LastModified,
|
||||||
resp.Header.Get("Expires"),
|
resp.Header.Get("Expires"),
|
||||||
|
c.username != "",
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ignore caching headers for feeds that do not want any cache.
|
// Ignore caching headers for feeds that do not want any cache.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-06-05 15:34:49.597679681 +0200 CEST m=+0.259287761
|
// 2018-06-19 22:56:40.321373022 -0700 PDT m=+0.043185142
|
||||||
|
|
||||||
package locale
|
package locale
|
||||||
|
|
||||||
|
@ -479,7 +479,10 @@ var translations = map[string]string{
|
||||||
"Pocket Access Token": "« Pocket Access Token »",
|
"Pocket Access Token": "« Pocket Access Token »",
|
||||||
"Your Pocket account is now linked!": "Votre compte Pocket est maintenant connecté !",
|
"Your Pocket account is now linked!": "Votre compte Pocket est maintenant connecté !",
|
||||||
"Unable to fetch access token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
"Unable to fetch access token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
||||||
"Unable to fetch request token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !"
|
"Unable to fetch request token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
||||||
|
"Advanced Options": "Options avancées",
|
||||||
|
"Feed Username": "Nom d'utilisateur du flux",
|
||||||
|
"Feed Password": "Mot de passe du flux"
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
"nl_NL": `{
|
"nl_NL": `{
|
||||||
|
@ -1154,7 +1157,7 @@ var translations = map[string]string{
|
||||||
var translationsChecksums = map[string]string{
|
var translationsChecksums = map[string]string{
|
||||||
"de_DE": "c6b06d144a57719194bc71da5911fee14659d77bb3deae7f3d6c28d1e019d366",
|
"de_DE": "c6b06d144a57719194bc71da5911fee14659d77bb3deae7f3d6c28d1e019d366",
|
||||||
"en_US": "6fe95384260941e8a5a3c695a655a932e0a8a6a572c1e45cb2b1ae8baa01b897",
|
"en_US": "6fe95384260941e8a5a3c695a655a932e0a8a6a572c1e45cb2b1ae8baa01b897",
|
||||||
"fr_FR": "808f1561135bb3d0f886833f00a51402113925e9086c01f71b30bcc679d9b7c2",
|
"fr_FR": "734b9ee6edc65e5c076fc91999d81f6c586eeb52f420101049bff9b501cbae54",
|
||||||
"nl_NL": "1a73f1dd1c4c0d2c2adc8695cdd050c2dad81c14876caed3892b44adc2491265",
|
"nl_NL": "1a73f1dd1c4c0d2c2adc8695cdd050c2dad81c14876caed3892b44adc2491265",
|
||||||
"pl_PL": "da709c14ff71f3b516eec66cb2758d89c5feab1472c94b2b518f425162a9f806",
|
"pl_PL": "da709c14ff71f3b516eec66cb2758d89c5feab1472c94b2b518f425162a9f806",
|
||||||
"zh_CN": "d80594c1b67d15e9f4673d3d62fe4949e8606a5fdfb741d8a8921f21dceb8cf2",
|
"zh_CN": "d80594c1b67d15e9f4673d3d62fe4949e8606a5fdfb741d8a8921f21dceb8cf2",
|
||||||
|
|
|
@ -229,5 +229,8 @@
|
||||||
"Pocket Access Token": "« Pocket Access Token »",
|
"Pocket Access Token": "« Pocket Access Token »",
|
||||||
"Your Pocket account is now linked!": "Votre compte Pocket est maintenant connecté !",
|
"Your Pocket account is now linked!": "Votre compte Pocket est maintenant connecté !",
|
||||||
"Unable to fetch access token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
"Unable to fetch access token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
||||||
"Unable to fetch request token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !"
|
"Unable to fetch request token from Pocket!": "Impossible de récupérer le jeton d'accès depuis Pocket !",
|
||||||
|
"Advanced Options": "Options avancées",
|
||||||
|
"Feed Username": "Nom d'utilisateur du flux",
|
||||||
|
"Feed Password": "Mot de passe du flux"
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ type Feed struct {
|
||||||
ScraperRules string `json:"scraper_rules"`
|
ScraperRules string `json:"scraper_rules"`
|
||||||
RewriteRules string `json:"rewrite_rules"`
|
RewriteRules string `json:"rewrite_rules"`
|
||||||
Crawler bool `json:"crawler"`
|
Crawler bool `json:"crawler"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
Category *Category `json:"category,omitempty"`
|
Category *Category `json:"category,omitempty"`
|
||||||
Entries Entries `json:"entries,omitempty"`
|
Entries Entries `json:"entries,omitempty"`
|
||||||
Icon *FeedIcon `json:"icon"`
|
Icon *FeedIcon `json:"icon"`
|
||||||
|
@ -69,6 +71,14 @@ func (f *Feed) Merge(override *Feed) {
|
||||||
if override.Category != nil && override.Category.ID != 0 && override.Category.ID != f.Category.ID {
|
if override.Category != nil && override.Category.ID != 0 && override.Category.ID != f.Category.ID {
|
||||||
f.Category.ID = override.Category.ID
|
f.Category.ID = override.Category.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if override.Username != f.Username {
|
||||||
|
f.Username = override.Username
|
||||||
|
}
|
||||||
|
|
||||||
|
if override.Password != f.Password {
|
||||||
|
f.Password = override.Password
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feeds is a list of feed
|
// Feeds is a list of feed
|
||||||
|
|
|
@ -36,7 +36,7 @@ type Handler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFeed fetch, parse and store a new feed.
|
// CreateFeed fetch, parse and store a new feed.
|
||||||
func (h *Handler) CreateFeed(userID, categoryID int64, url string, crawler bool) (*model.Feed, error) {
|
func (h *Handler) CreateFeed(userID, categoryID int64, url string, crawler bool, username, password string) (*model.Feed, error) {
|
||||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Handler:CreateFeed] feedUrl=%s", url))
|
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Handler:CreateFeed] feedUrl=%s", url))
|
||||||
|
|
||||||
if !h.store.CategoryExists(userID, categoryID) {
|
if !h.store.CategoryExists(userID, categoryID) {
|
||||||
|
@ -44,6 +44,7 @@ func (h *Handler) CreateFeed(userID, categoryID int64, url string, crawler bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
clt := client.New(url)
|
clt := client.New(url)
|
||||||
|
clt.WithCredentials(username, password)
|
||||||
response, err := clt.Get()
|
response, err := clt.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(*errors.LocalizedError); ok {
|
if _, ok := err.(*errors.LocalizedError); ok {
|
||||||
|
@ -85,6 +86,8 @@ func (h *Handler) CreateFeed(userID, categoryID int64, url string, crawler bool)
|
||||||
subscription.FeedURL = response.EffectiveURL
|
subscription.FeedURL = response.EffectiveURL
|
||||||
subscription.UserID = userID
|
subscription.UserID = userID
|
||||||
subscription.Crawler = crawler
|
subscription.Crawler = crawler
|
||||||
|
subscription.Username = username
|
||||||
|
subscription.Password = password
|
||||||
|
|
||||||
if subscription.SiteURL == "" {
|
if subscription.SiteURL == "" {
|
||||||
subscription.SiteURL = subscription.FeedURL
|
subscription.SiteURL = subscription.FeedURL
|
||||||
|
@ -130,6 +133,7 @@ func (h *Handler) RefreshFeed(userID, feedID int64) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
clt := client.New(originalFeed.FeedURL)
|
clt := client.New(originalFeed.FeedURL)
|
||||||
|
clt.WithCredentials(originalFeed.Username, originalFeed.Password)
|
||||||
clt.WithCacheHeaders(originalFeed.EtagHeader, originalFeed.LastModifiedHeader)
|
clt.WithCacheHeaders(originalFeed.EtagHeader, originalFeed.LastModifiedHeader)
|
||||||
response, err := clt.Get()
|
response, err := clt.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -27,10 +27,11 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// FindSubscriptions downloads and try to find one or more subscriptions from an URL.
|
// FindSubscriptions downloads and try to find one or more subscriptions from an URL.
|
||||||
func FindSubscriptions(websiteURL string) (Subscriptions, error) {
|
func FindSubscriptions(websiteURL, username, password string) (Subscriptions, error) {
|
||||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[FindSubscriptions] url=%s", websiteURL))
|
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[FindSubscriptions] url=%s", websiteURL))
|
||||||
|
|
||||||
clt := client.New(websiteURL)
|
clt := client.New(websiteURL)
|
||||||
|
clt.WithCredentials(username, password)
|
||||||
response, err := clt.Get()
|
response, err := clt.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(errors.LocalizedError); ok {
|
if _, ok := err.(errors.LocalizedError); ok {
|
||||||
|
|
2
sql/schema_version_19.sql
Normal file
2
sql/schema_version_19.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
alter table feeds add column username text default '';
|
||||||
|
alter table feeds add column password text default '';
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-05-21 12:33:12.475674107 -0700 PDT m=+0.003076147
|
// 2018-06-19 22:56:40.283528941 -0700 PDT m=+0.005341061
|
||||||
|
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
|
@ -136,6 +136,8 @@ alter table integrations add column pocket_access_token text default '';
|
||||||
alter table integrations add column pocket_consumer_key text default '';
|
alter table integrations add column pocket_consumer_key text default '';
|
||||||
`,
|
`,
|
||||||
"schema_version_18": `alter table user_sessions alter column ip set data type inet using ip::inet;`,
|
"schema_version_18": `alter table user_sessions alter column ip set data type inet using ip::inet;`,
|
||||||
|
"schema_version_19": `alter table feeds add column username text default '';
|
||||||
|
alter table feeds add column password text default '';`,
|
||||||
"schema_version_2": `create extension if not exists hstore;
|
"schema_version_2": `create extension if not exists hstore;
|
||||||
alter table users add column extra hstore;
|
alter table users add column extra hstore;
|
||||||
create index users_extra_idx on users using gin(extra);
|
create index users_extra_idx on users using gin(extra);
|
||||||
|
@ -185,6 +187,7 @@ var SqlMapChecksums = map[string]string{
|
||||||
"schema_version_16": "9d006faca62fd7ab787f64aef0e0a5933d142466ec4cab0e096bb920d2797e34",
|
"schema_version_16": "9d006faca62fd7ab787f64aef0e0a5933d142466ec4cab0e096bb920d2797e34",
|
||||||
"schema_version_17": "b9f15d6217275fedcf6d948dd85ebe978b869bf37f42a86fd5b50a51919fa0e1",
|
"schema_version_17": "b9f15d6217275fedcf6d948dd85ebe978b869bf37f42a86fd5b50a51919fa0e1",
|
||||||
"schema_version_18": "c0ec24847612c7f2dc326cf735baffba79391a56aedd73292371a39f38724a71",
|
"schema_version_18": "c0ec24847612c7f2dc326cf735baffba79391a56aedd73292371a39f38724a71",
|
||||||
|
"schema_version_19": "a83f77b41cc213d282805a5b518f15abbf96331599119f0ef4aca4be037add7b",
|
||||||
"schema_version_2": "e8e9ff32478df04fcddad10a34cba2e8bb1e67e7977b5bd6cdc4c31ec94282b4",
|
"schema_version_2": "e8e9ff32478df04fcddad10a34cba2e8bb1e67e7977b5bd6cdc4c31ec94282b4",
|
||||||
"schema_version_3": "a54745dbc1c51c000f74d4e5068f1e2f43e83309f023415b1749a47d5c1e0f12",
|
"schema_version_3": "a54745dbc1c51c000f74d4e5068f1e2f43e83309f023415b1749a47d5c1e0f12",
|
||||||
"schema_version_4": "216ea3a7d3e1704e40c797b5dc47456517c27dbb6ca98bf88812f4f63d74b5d9",
|
"schema_version_4": "216ea3a7d3e1704e40c797b5dc47456517c27dbb6ca98bf88812f4f63d74b5d9",
|
||||||
|
|
|
@ -56,6 +56,7 @@ func (s *Storage) Feeds(userID int64) (model.Feeds, error) {
|
||||||
f.user_id, f.checked_at at time zone u.timezone,
|
f.user_id, f.checked_at at time zone u.timezone,
|
||||||
f.parsing_error_count, f.parsing_error_msg,
|
f.parsing_error_count, f.parsing_error_msg,
|
||||||
f.scraper_rules, f.rewrite_rules, f.crawler,
|
f.scraper_rules, f.rewrite_rules, f.crawler,
|
||||||
|
f.username, f.password,
|
||||||
f.category_id, c.title as category_title,
|
f.category_id, c.title as category_title,
|
||||||
fi.icon_id,
|
fi.icon_id,
|
||||||
u.timezone
|
u.timezone
|
||||||
|
@ -92,6 +93,8 @@ func (s *Storage) Feeds(userID int64) (model.Feeds, error) {
|
||||||
&feed.ScraperRules,
|
&feed.ScraperRules,
|
||||||
&feed.RewriteRules,
|
&feed.RewriteRules,
|
||||||
&feed.Crawler,
|
&feed.Crawler,
|
||||||
|
&feed.Username,
|
||||||
|
&feed.Password,
|
||||||
&feed.Category.ID,
|
&feed.Category.ID,
|
||||||
&feed.Category.Title,
|
&feed.Category.Title,
|
||||||
&iconID,
|
&iconID,
|
||||||
|
@ -128,6 +131,7 @@ func (s *Storage) FeedByID(userID, feedID int64) (*model.Feed, error) {
|
||||||
f.user_id, f.checked_at at time zone u.timezone,
|
f.user_id, f.checked_at at time zone u.timezone,
|
||||||
f.parsing_error_count, f.parsing_error_msg,
|
f.parsing_error_count, f.parsing_error_msg,
|
||||||
f.scraper_rules, f.rewrite_rules, f.crawler,
|
f.scraper_rules, f.rewrite_rules, f.crawler,
|
||||||
|
f.username, f.password,
|
||||||
f.category_id, c.title as category_title,
|
f.category_id, c.title as category_title,
|
||||||
fi.icon_id,
|
fi.icon_id,
|
||||||
u.timezone
|
u.timezone
|
||||||
|
@ -151,6 +155,8 @@ func (s *Storage) FeedByID(userID, feedID int64) (*model.Feed, error) {
|
||||||
&feed.ScraperRules,
|
&feed.ScraperRules,
|
||||||
&feed.RewriteRules,
|
&feed.RewriteRules,
|
||||||
&feed.Crawler,
|
&feed.Crawler,
|
||||||
|
&feed.Username,
|
||||||
|
&feed.Password,
|
||||||
&feed.Category.ID,
|
&feed.Category.ID,
|
||||||
&feed.Category.Title,
|
&feed.Category.Title,
|
||||||
&iconID,
|
&iconID,
|
||||||
|
@ -177,8 +183,8 @@ func (s *Storage) CreateFeed(feed *model.Feed) error {
|
||||||
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:CreateFeed] feedURL=%s", feed.FeedURL))
|
defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:CreateFeed] feedURL=%s", feed.FeedURL))
|
||||||
sql := `
|
sql := `
|
||||||
INSERT INTO feeds
|
INSERT INTO feeds
|
||||||
(feed_url, site_url, title, category_id, user_id, etag_header, last_modified_header, crawler)
|
(feed_url, site_url, title, category_id, user_id, etag_header, last_modified_header, crawler, username, password)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
||||||
RETURNING id
|
RETURNING id
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -192,6 +198,8 @@ func (s *Storage) CreateFeed(feed *model.Feed) error {
|
||||||
feed.EtagHeader,
|
feed.EtagHeader,
|
||||||
feed.LastModifiedHeader,
|
feed.LastModifiedHeader,
|
||||||
feed.Crawler,
|
feed.Crawler,
|
||||||
|
feed.Username,
|
||||||
|
feed.Password,
|
||||||
).Scan(&feed.ID)
|
).Scan(&feed.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create feed: %v", err)
|
return fmt.Errorf("unable to create feed: %v", err)
|
||||||
|
@ -215,8 +223,9 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) {
|
||||||
|
|
||||||
query := `UPDATE feeds SET
|
query := `UPDATE feeds SET
|
||||||
feed_url=$1, site_url=$2, title=$3, category_id=$4, etag_header=$5, last_modified_header=$6, checked_at=$7,
|
feed_url=$1, site_url=$2, title=$3, category_id=$4, etag_header=$5, last_modified_header=$6, checked_at=$7,
|
||||||
parsing_error_msg=$8, parsing_error_count=$9, scraper_rules=$10, rewrite_rules=$11, crawler=$12
|
parsing_error_msg=$8, parsing_error_count=$9, scraper_rules=$10, rewrite_rules=$11, crawler=$12,
|
||||||
WHERE id=$13 AND user_id=$14`
|
username=$13, password=$14
|
||||||
|
WHERE id=$15 AND user_id=$16`
|
||||||
|
|
||||||
_, err = s.db.Exec(query,
|
_, err = s.db.Exec(query,
|
||||||
feed.FeedURL,
|
feed.FeedURL,
|
||||||
|
@ -231,6 +240,8 @@ func (s *Storage) UpdateFeed(feed *model.Feed) (err error) {
|
||||||
feed.ScraperRules,
|
feed.ScraperRules,
|
||||||
feed.RewriteRules,
|
feed.RewriteRules,
|
||||||
feed.Crawler,
|
feed.Crawler,
|
||||||
|
feed.Username,
|
||||||
|
feed.Password,
|
||||||
feed.ID,
|
feed.ID,
|
||||||
feed.UserID,
|
feed.UserID,
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/miniflux/miniflux/sql"
|
"github.com/miniflux/miniflux/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
const schemaVersion = 18
|
const schemaVersion = 19
|
||||||
|
|
||||||
// Migrate run database migrations.
|
// Migrate run database migrations.
|
||||||
func (s *Storage) Migrate() {
|
func (s *Storage) Migrate() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-05-21 12:40:10.613112 +0200 CEST m=+0.010961753
|
// 2018-06-19 22:56:40.319198468 -0700 PDT m=+0.041010588
|
||||||
|
|
||||||
package template
|
package template
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,18 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{ t "Advanced Options" }}</legend>
|
||||||
|
|
||||||
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
||||||
|
|
||||||
|
<label for="form-username">{{ t "Feed Username" }}</label>
|
||||||
|
<input type="text" name="username" id="form-username" value="{{ .form.Username }}">
|
||||||
|
|
||||||
|
<label for="form-password">{{ t "Feed Password" }}</label>
|
||||||
|
<input type="password" name="password" id="form-password" value="{{ .form.Password }}">
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Find a subscription" }}</button>
|
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Find a subscription" }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,7 +18,12 @@
|
||||||
|
|
||||||
<form action="{{ route "chooseSubscription" }}" method="POST">
|
<form action="{{ route "chooseSubscription" }}" method="POST">
|
||||||
<input type="hidden" name="csrf" value="{{ .csrf }}">
|
<input type="hidden" name="csrf" value="{{ .csrf }}">
|
||||||
<input type="hidden" name="category_id" value="{{ .categoryID }}">
|
<input type="hidden" name="category_id" value="{{ .form.CategoryID }}">
|
||||||
|
<input type="hidden" name="username" value="{{ .form.Username }}">
|
||||||
|
<input type="hidden" name="password" value="{{ .form.Password }}">
|
||||||
|
{{ if .form.Crawler }}
|
||||||
|
<input type="hidden" name="crawler" value="1">
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
<h3>{{ t "Choose a Subscription" }}</h3>
|
<h3>{{ t "Choose a Subscription" }}</h3>
|
||||||
|
|
||||||
|
@ -29,9 +34,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<br>
|
|
||||||
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Subscribe" }}</button>
|
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Subscribe" }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -45,6 +45,12 @@
|
||||||
<label for="form-feed-url">{{ t "Feed URL" }}</label>
|
<label for="form-feed-url">{{ t "Feed URL" }}</label>
|
||||||
<input type="url" name="feed_url" id="form-feed-url" placeholder="https://domain.tld/" value="{{ .form.FeedURL }}" required>
|
<input type="url" name="feed_url" id="form-feed-url" placeholder="https://domain.tld/" value="{{ .form.FeedURL }}" required>
|
||||||
|
|
||||||
|
<label for="form-username">{{ t "Feed Username" }}</label>
|
||||||
|
<input type="text" name="username" id="form-username" value="{{ .form.Username }}">
|
||||||
|
|
||||||
|
<label for="form-password">{{ t "Feed Password" }}</label>
|
||||||
|
<input type="password" name="password" id="form-password" value="{{ .form.Password }}">
|
||||||
|
|
||||||
<label for="form-scraper-rules">{{ t "Scraper Rules" }}</label>
|
<label for="form-scraper-rules">{{ t "Scraper Rules" }}</label>
|
||||||
<input type="text" name="scraper_rules" id="form-scraper-rules" value="{{ .form.ScraperRules }}">
|
<input type="text" name="scraper_rules" id="form-scraper-rules" value="{{ .form.ScraperRules }}">
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-05-21 12:14:59.39668234 -0700 PDT m=+0.007850936
|
// 2018-06-19 22:56:40.310658103 -0700 PDT m=+0.032470223
|
||||||
|
|
||||||
package template
|
package template
|
||||||
|
|
||||||
|
@ -83,8 +83,18 @@ var templateViewsMap = map[string]string{
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{ t "Advanced Options" }}</legend>
|
||||||
|
|
||||||
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
||||||
|
|
||||||
|
<label for="form-username">{{ t "Feed Username" }}</label>
|
||||||
|
<input type="text" name="username" id="form-username" value="{{ .form.Username }}">
|
||||||
|
|
||||||
|
<label for="form-password">{{ t "Feed Password" }}</label>
|
||||||
|
<input type="password" name="password" id="form-password" value="{{ .form.Password }}">
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Find a subscription" }}</button>
|
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Find a subscription" }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -239,7 +249,12 @@ var templateViewsMap = map[string]string{
|
||||||
|
|
||||||
<form action="{{ route "chooseSubscription" }}" method="POST">
|
<form action="{{ route "chooseSubscription" }}" method="POST">
|
||||||
<input type="hidden" name="csrf" value="{{ .csrf }}">
|
<input type="hidden" name="csrf" value="{{ .csrf }}">
|
||||||
<input type="hidden" name="category_id" value="{{ .categoryID }}">
|
<input type="hidden" name="category_id" value="{{ .form.CategoryID }}">
|
||||||
|
<input type="hidden" name="username" value="{{ .form.Username }}">
|
||||||
|
<input type="hidden" name="password" value="{{ .form.Password }}">
|
||||||
|
{{ if .form.Crawler }}
|
||||||
|
<input type="hidden" name="crawler" value="1">
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
<h3>{{ t "Choose a Subscription" }}</h3>
|
<h3>{{ t "Choose a Subscription" }}</h3>
|
||||||
|
|
||||||
|
@ -250,9 +265,6 @@ var templateViewsMap = map[string]string{
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<br>
|
|
||||||
<label><input type="checkbox" name="crawler" value="1" {{ if .form.Crawler }}checked{{ end }}> {{ t "Fetch original content" }}</label>
|
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Subscribe" }}</button>
|
<button type="submit" class="button button-primary" data-label-loading="{{ t "Loading..." }}">{{ t "Subscribe" }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -413,6 +425,12 @@ var templateViewsMap = map[string]string{
|
||||||
<label for="form-feed-url">{{ t "Feed URL" }}</label>
|
<label for="form-feed-url">{{ t "Feed URL" }}</label>
|
||||||
<input type="url" name="feed_url" id="form-feed-url" placeholder="https://domain.tld/" value="{{ .form.FeedURL }}" required>
|
<input type="url" name="feed_url" id="form-feed-url" placeholder="https://domain.tld/" value="{{ .form.FeedURL }}" required>
|
||||||
|
|
||||||
|
<label for="form-username">{{ t "Feed Username" }}</label>
|
||||||
|
<input type="text" name="username" id="form-username" value="{{ .form.Username }}">
|
||||||
|
|
||||||
|
<label for="form-password">{{ t "Feed Password" }}</label>
|
||||||
|
<input type="password" name="password" id="form-password" value="{{ .form.Password }}">
|
||||||
|
|
||||||
<label for="form-scraper-rules">{{ t "Scraper Rules" }}</label>
|
<label for="form-scraper-rules">{{ t "Scraper Rules" }}</label>
|
||||||
<input type="text" name="scraper_rules" id="form-scraper-rules" value="{{ .form.ScraperRules }}">
|
<input type="text" name="scraper_rules" id="form-scraper-rules" value="{{ .form.ScraperRules }}">
|
||||||
|
|
||||||
|
@ -1250,15 +1268,15 @@ var templateViewsMap = map[string]string{
|
||||||
|
|
||||||
var templateViewsMapChecksums = map[string]string{
|
var templateViewsMapChecksums = map[string]string{
|
||||||
"about": "ad2fb778fc73c39b733b3f81b13e5c7d689b041fadd24ee2d4577f545aa788ad",
|
"about": "ad2fb778fc73c39b733b3f81b13e5c7d689b041fadd24ee2d4577f545aa788ad",
|
||||||
"add_subscription": "053c920b0d7e109ea19dce6a448e304ce720db8633588ea04db16677f7209a7b",
|
"add_subscription": "5067776ce452543fceed8b62defe5fbfed41e3d5bd79b5f2acf8c45ef4faac6d",
|
||||||
"bookmark_entries": "8e5fea7559218a34289c2f0e54955fc0ef3b9e629205927841cbcc2276aefb2a",
|
"bookmark_entries": "8e5fea7559218a34289c2f0e54955fc0ef3b9e629205927841cbcc2276aefb2a",
|
||||||
"categories": "ca1280cd157bb527d4fc907da67b05a8347378f6dce965b9389d4bcdf3600a11",
|
"categories": "ca1280cd157bb527d4fc907da67b05a8347378f6dce965b9389d4bcdf3600a11",
|
||||||
"category_entries": "6ad52c8d0c28e21ea48be76228ea8432adde1dc190010753a48928477d52e065",
|
"category_entries": "6ad52c8d0c28e21ea48be76228ea8432adde1dc190010753a48928477d52e065",
|
||||||
"choose_subscription": "a325f9c976ca2b2dc148e25c8fef0cf6ccab0e04e86e604e7812bb18dc4cdde1",
|
"choose_subscription": "c680e690255d53da1f4f11e9b997bc2a32ca659f1245076e5738243859e17876",
|
||||||
"create_category": "2b82af5d2dcd67898dc5daa57a6461e6ff8121a6089b2a2a1be909f35e4a2275",
|
"create_category": "2b82af5d2dcd67898dc5daa57a6461e6ff8121a6089b2a2a1be909f35e4a2275",
|
||||||
"create_user": "233764778c915754141a20429ec8db9bf80ef2d7704867a2d7232c1e9df233ae",
|
"create_user": "233764778c915754141a20429ec8db9bf80ef2d7704867a2d7232c1e9df233ae",
|
||||||
"edit_category": "cee720faadcec58289b707ad30af623d2ee66c1ce23a732965463250d7ff41c5",
|
"edit_category": "cee720faadcec58289b707ad30af623d2ee66c1ce23a732965463250d7ff41c5",
|
||||||
"edit_feed": "d2c1c8486d7faf4ee58151ccf3e3c690e53bd6872050d291c5db8452a83c3d53",
|
"edit_feed": "66dd3ca6357645944a99f8b9c0455253e6d2bf5f36faf9aa322689b6299b0104",
|
||||||
"edit_user": "321e0a60cf3bf7441bff970f4920e4c5b7c1883f80ab1d1674f8137954b25033",
|
"edit_user": "321e0a60cf3bf7441bff970f4920e4c5b7c1883f80ab1d1674f8137954b25033",
|
||||||
"entry": "bd611521ebb46714fce434fe7fa5d4e53e50da4c3ed02450ad3557f614f16e14",
|
"entry": "bd611521ebb46714fce434fe7fa5d4e53e50da4c3ed02450ad3557f614f16e14",
|
||||||
"feed_entries": "4dffdb55cfad29df20612efe7ed2dbed03d919c4556898543ab6450f610d3c99",
|
"feed_entries": "4dffdb55cfad29df20612efe7ed2dbed03d919c4556898543ab6450f610d3c99",
|
||||||
|
|
|
@ -56,6 +56,8 @@ func (c *Controller) EditFeed(w http.ResponseWriter, r *http.Request) {
|
||||||
RewriteRules: feed.RewriteRules,
|
RewriteRules: feed.RewriteRules,
|
||||||
Crawler: feed.Crawler,
|
Crawler: feed.Crawler,
|
||||||
CategoryID: feed.Category.ID,
|
CategoryID: feed.Category.ID,
|
||||||
|
Username: feed.Username,
|
||||||
|
Password: feed.Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
sess := session.New(c.store, ctx)
|
sess := session.New(c.store, ctx)
|
||||||
|
|
|
@ -21,6 +21,8 @@ type FeedForm struct {
|
||||||
RewriteRules string
|
RewriteRules string
|
||||||
Crawler bool
|
Crawler bool
|
||||||
CategoryID int64
|
CategoryID int64
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateModification validates FeedForm fields
|
// ValidateModification validates FeedForm fields
|
||||||
|
@ -42,6 +44,8 @@ func (f FeedForm) Merge(feed *model.Feed) *model.Feed {
|
||||||
feed.Crawler = f.Crawler
|
feed.Crawler = f.Crawler
|
||||||
feed.ParsingErrorCount = 0
|
feed.ParsingErrorCount = 0
|
||||||
feed.ParsingErrorMsg = ""
|
feed.ParsingErrorMsg = ""
|
||||||
|
feed.Username = f.Username
|
||||||
|
feed.Password = f.Password
|
||||||
return feed
|
return feed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,5 +64,7 @@ func NewFeedForm(r *http.Request) *FeedForm {
|
||||||
RewriteRules: r.FormValue("rewrite_rules"),
|
RewriteRules: r.FormValue("rewrite_rules"),
|
||||||
Crawler: r.FormValue("crawler") == "1",
|
Crawler: r.FormValue("crawler") == "1",
|
||||||
CategoryID: int64(categoryID),
|
CategoryID: int64(categoryID),
|
||||||
|
Username: r.FormValue("username"),
|
||||||
|
Password: r.FormValue("password"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ type SubscriptionForm struct {
|
||||||
URL string
|
URL string
|
||||||
CategoryID int64
|
CategoryID int64
|
||||||
Crawler bool
|
Crawler bool
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate makes sure the form values are valid.
|
// Validate makes sure the form values are valid.
|
||||||
|
@ -38,5 +40,7 @@ func NewSubscriptionForm(r *http.Request) *SubscriptionForm {
|
||||||
URL: r.FormValue("url"),
|
URL: r.FormValue("url"),
|
||||||
Crawler: r.FormValue("crawler") == "1",
|
Crawler: r.FormValue("crawler") == "1",
|
||||||
CategoryID: int64(categoryID),
|
CategoryID: int64(categoryID),
|
||||||
|
Username: r.FormValue("username"),
|
||||||
|
Password: r.FormValue("password"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-05-20 15:22:33.779971968 -0700 PDT m=+0.011442481
|
// 2018-06-19 22:56:40.300982018 -0700 PDT m=+0.022794138
|
||||||
|
|
||||||
package static
|
package static
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -184,6 +184,17 @@ tr:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forms */
|
/* Forms */
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
font-weight: 500;
|
||||||
|
padding-left: 3px;
|
||||||
|
padding-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Code generated by go generate; DO NOT EDIT.
|
// Code generated by go generate; DO NOT EDIT.
|
||||||
// 2018-06-06 18:30:00.64689124 +0000 UTC m=+0.004975400
|
// 2018-06-19 22:56:40.308801738 -0700 PDT m=+0.030613858
|
||||||
|
|
||||||
package static
|
package static
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,14 @@ func (c *Controller) ChooseSubscription(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
feed, err := c.feedHandler.CreateFeed(user.ID, subscriptionForm.CategoryID, subscriptionForm.URL, subscriptionForm.Crawler)
|
feed, err := c.feedHandler.CreateFeed(
|
||||||
|
user.ID,
|
||||||
|
subscriptionForm.CategoryID,
|
||||||
|
subscriptionForm.URL,
|
||||||
|
subscriptionForm.Crawler,
|
||||||
|
subscriptionForm.Username,
|
||||||
|
subscriptionForm.Password,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
view.Set("form", subscriptionForm)
|
view.Set("form", subscriptionForm)
|
||||||
view.Set("errorMessage", err)
|
view.Set("errorMessage", err)
|
||||||
|
|
|
@ -49,7 +49,11 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions, err := subscription.FindSubscriptions(subscriptionForm.URL)
|
subscriptions, err := subscription.FindSubscriptions(
|
||||||
|
subscriptionForm.URL,
|
||||||
|
subscriptionForm.Username,
|
||||||
|
subscriptionForm.Password,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("[Controller:SubmitSubscription] %v", err)
|
logger.Error("[Controller:SubmitSubscription] %v", err)
|
||||||
v.Set("form", subscriptionForm)
|
v.Set("form", subscriptionForm)
|
||||||
|
@ -67,7 +71,14 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
|
||||||
v.Set("errorMessage", "Unable to find any subscription.")
|
v.Set("errorMessage", "Unable to find any subscription.")
|
||||||
html.OK(w, v.Render("add_subscription"))
|
html.OK(w, v.Render("add_subscription"))
|
||||||
case n == 1:
|
case n == 1:
|
||||||
feed, err := c.feedHandler.CreateFeed(user.ID, subscriptionForm.CategoryID, subscriptions[0].URL, subscriptionForm.Crawler)
|
feed, err := c.feedHandler.CreateFeed(
|
||||||
|
user.ID,
|
||||||
|
subscriptionForm.CategoryID,
|
||||||
|
subscriptions[0].URL,
|
||||||
|
subscriptionForm.Crawler,
|
||||||
|
subscriptionForm.Username,
|
||||||
|
subscriptionForm.Password,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.Set("form", subscriptionForm)
|
v.Set("form", subscriptionForm)
|
||||||
v.Set("errorMessage", err)
|
v.Set("errorMessage", err)
|
||||||
|
@ -79,7 +90,7 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
|
||||||
case n > 1:
|
case n > 1:
|
||||||
v := view.New(c.tpl, ctx, sess)
|
v := view.New(c.tpl, ctx, sess)
|
||||||
v.Set("subscriptions", subscriptions)
|
v.Set("subscriptions", subscriptions)
|
||||||
v.Set("categoryID", subscriptionForm.CategoryID)
|
v.Set("form", subscriptionForm)
|
||||||
v.Set("menu", "feeds")
|
v.Set("menu", "feeds")
|
||||||
v.Set("user", user)
|
v.Set("user", user)
|
||||||
v.Set("countUnread", c.store.CountUnreadEntries(user.ID))
|
v.Set("countUnread", c.store.CountUnreadEntries(user.ID))
|
||||||
|
|
Loading…
Reference in a new issue