Example #1
0
func removeFolder(pfc *PFContext) (interface{}, error) {
	r := pfc.R

	folderID := r.PostFormValue("folder")
	if folderID == "" {
		return nil, NewReadableError(_l("Folder not found"), nil)
	}

	folderRef := storage.FolderRef{
		UserID:   pfc.UserID,
		FolderID: folderID,
	}

	if exists, err := storage.FolderExists(pfc.C, folderRef); err != nil {
		return nil, err
	} else if !exists {
		return nil, NewReadableError(_l("Folder not found"), nil)
	}

	// Delete the folder and subscriptions
	if err := storage.DeleteFolder(pfc.C, folderRef); err != nil {
		return nil, err
	}

	// Start a task to purge the articles
	params := taskParams{
		"folderID": folderID,
	}
	if err := startTask(pfc, "removeFolder", params, modificationQueue); err != nil {
		return nil, NewReadableError(_l("Cannot unsubscribe - too busy"), &err)
	}

	return storage.NewUserSubscriptions(pfc.C, pfc.UserID)
}
Example #2
0
func moveSubscription(pfc *PFContext) (interface{}, error) {
	r := pfc.R

	subscriptionID := r.PostFormValue("subscription")
	folderID := r.PostFormValue("folder")
	destinationID := r.PostFormValue("destination")

	destination := storage.FolderRef{
		UserID:   pfc.UserID,
		FolderID: destinationID,
	}

	if destinationID != "" {
		if exists, err := storage.FolderExists(pfc.C, destination); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Folder not found"), nil)
		}
	}

	ref := storage.SubscriptionRef{
		FolderRef: storage.FolderRef{
			UserID:   pfc.UserID,
			FolderID: folderID,
		},
		SubscriptionID: subscriptionID,
	}

	if exists, err := storage.SubscriptionExists(pfc.C, ref); err != nil {
		return nil, err
	} else if !exists {
		return nil, NewReadableError(_l("Subscription not found"), nil)
	}

	if err := storage.MoveSubscription(pfc.C, ref, destination); err != nil {
		return nil, err
	}

	params := taskParams{
		"subscriptionID": subscriptionID,
		"folderID":       folderID,
		"destinationID":  destinationID,
	}

	if err := startTask(pfc, "moveSubscription", params, modificationQueue); err != nil {
		return nil, err
	}

	return storage.NewUserSubscriptions(pfc.C, pfc.UserID)
}
Example #3
0
func rename(pfc *PFContext) (interface{}, error) {
	r := pfc.R

	title := r.PostFormValue("title")
	if title == "" {
		return nil, NewReadableError(_l("Name not specified"), nil)
	}

	ref, err := storage.SubscriptionRefFromJSON(pfc.UserID, r.PostFormValue("ref"))
	if err != nil {
		return nil, err
	}

	if ref.IsSubscriptionExplicit() {
		if exists, err := storage.SubscriptionExists(pfc.C, ref); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Subscription not found"), nil)
		}

		if err := storage.RenameSubscription(pfc.C, ref, title); err != nil {
			return nil, NewReadableError(_l("Error renaming subscription"), &err)
		}
	} else {
		if exists, err := storage.FolderExists(pfc.C, ref.FolderRef); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Folder not found"), nil)
		}

		if isDupe, err := storage.IsFolderDuplicate(pfc.C, pfc.UserID, title); err != nil {
			return nil, err
		} else if isDupe {
			return nil, NewReadableError(_l("A folder with that name already exists"), nil)
		}

		if err := storage.RenameFolder(pfc.C, ref.FolderRef, title); err != nil {
			return nil, NewReadableError(_l("Error renaming folder"), &err)
		}
	}

	return storage.NewUserSubscriptions(pfc.C, pfc.UserID)
}
Example #4
0
func markAllAsRead(pfc *PFContext) (interface{}, error) {
	r := pfc.R

	subscriptionID := r.PostFormValue("subscription")
	folderID := r.PostFormValue("folder")

	if subscriptionID != "" {
		ref := storage.SubscriptionRef{
			FolderRef: storage.FolderRef{
				UserID:   pfc.UserID,
				FolderID: folderID,
			},
			SubscriptionID: subscriptionID,
		}
		if exists, err := storage.SubscriptionExists(pfc.C, ref); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Subscription not found"), nil)
		}
	} else if folderID != "" {
		ref := storage.FolderRef{
			UserID:   pfc.UserID,
			FolderID: folderID,
		}

		if exists, err := storage.FolderExists(pfc.C, ref); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Folder not found"), nil)
		}
	}

	params := taskParams{
		"subscriptionID": subscriptionID,
		"folderID":       folderID,
	}
	if err := startTask(pfc, "markAllAsRead", params, modificationQueue); err != nil {
		return nil, err
	}

	return _l("Please wait…"), nil
}
Example #5
0
func subscribe(pfc *PFContext) (interface{}, error) {
	c := pfc.C
	r := pfc.R

	subscriptionURL := r.PostFormValue("url")
	folderId := r.PostFormValue("folder")

	if subscriptionURL == "" {
		return nil, NewReadableError(_l("Missing URL"), nil)
	} else if _, err := url.ParseRequestURI(subscriptionURL); err != nil {
		return nil, NewReadableError(_l("URL is not valid"), &err)
	}

	folderRef := storage.FolderRef{
		UserID:   pfc.UserID,
		FolderID: folderId,
	}

	if folderId != "" {
		if exists, err := storage.FolderExists(pfc.C, folderRef); err != nil {
			return nil, err
		} else if !exists {
			return nil, NewReadableError(_l("Folder not found"), nil)
		}
	}

	feedTitle := _l("New Subscription")

	if exists, err := storage.IsFeedAvailable(pfc.C, subscriptionURL); err != nil {
		return nil, err
	} else if !exists {
		// Not a known feed URL
		// Match it against a list of known WWW links
		if feedURL, err := storage.WebToFeedURL(pfc.C, subscriptionURL, &feedTitle); err != nil {
			return nil, err
		} else if feedURL != "" {
			subscriptionURL = feedURL
		} else {
			// Still nothing
			// Add/remove 'www' to/from URL and try again
			var modifiedURL string
			if re := regexp.MustCompile(`://www\.`); re.MatchString(subscriptionURL) {
				modifiedURL = re.ReplaceAllString(subscriptionURL, "://")
			} else {
				re = regexp.MustCompile(`://`)
				modifiedURL = re.ReplaceAllString(subscriptionURL, "://www.")
			}

			if feedURL, err := storage.WebToFeedURL(pfc.C, modifiedURL, &feedTitle); err != nil {
				return nil, err
			} else if feedURL != "" {
				subscriptionURL = feedURL
			}
		}
	} else if feed, err := storage.FeedByURL(pfc.C, subscriptionURL); err == nil {
		if feed.Title != "" {
			feedTitle = feed.Title
		}
	}

	if subscribed, err := storage.IsSubscriptionDuplicate(pfc.C, pfc.UserID, subscriptionURL); err != nil {
		return nil, err
	} else if subscribed {
		return nil, NewReadableError(_l("You are already subscribed to %s", feedTitle), nil)
	}

	// At this point, the URL may have been re-written, so we check again
	if exists, err := storage.IsFeedAvailable(pfc.C, subscriptionURL); err != nil {
		return nil, err
	} else if !exists {
		// Don't have the feed locally - fetch it
		client := createHttpClient(c)
		if response, err := client.Get(subscriptionURL); err != nil {
			return nil, NewReadableError(_l("An error occurred while downloading the feed"), &err)
		} else {
			defer response.Body.Close()

			var body string
			if bytes, err := ioutil.ReadAll(response.Body); err != nil {
				return nil, NewReadableError(_l("An error occurred while reading the feed"), &err)
			} else {
				body = string(bytes)
			}

			reader := strings.NewReader(body)
			if feed, err := rss.UnmarshalStream(subscriptionURL, reader); err != nil {
				c.Warningf("Error parsing RSS (URL %s): %s", subscriptionURL, err)

				// Parse failed. Assume it's an HTML document and
				// try to pull out an RSS <link />
				if linkURL, err := rss.ExtractRSSLink(c, subscriptionURL, body); linkURL == "" || err != nil {
					return nil, NewReadableError(_l("RSS content not found (and no RSS links to follow)"), &err)
				} else {
					// Validate the RSS file
					if response, err := client.Get(linkURL); err != nil {
						return nil, NewReadableError(_l("An error occurred while downloading the feed"), &err)
					} else {
						defer response.Body.Close()

						if feed, err := rss.UnmarshalStream(linkURL, response.Body); err != nil {
							return nil, NewReadableError(_l("RSS content not found"), &err)
						} else {
							feedTitle = feed.Title
						}

						subscriptionURL = linkURL
					}
				}
			} else {
				feedTitle = feed.Title
			}
		}
	} else if feed, err := storage.FeedByURL(pfc.C, subscriptionURL); err == nil {
		if feed.Title != "" {
			feedTitle = feed.Title
		}
	}

	// Create subscription entry
	if _, err := storage.Subscribe(pfc.C, folderRef, subscriptionURL, feedTitle); err != nil {
		return nil, NewReadableError(_l("Cannot subscribe"), &err)
	}

	params := taskParams{
		"url":      subscriptionURL,
		"folderID": folderId,
	}
	if err := startTask(pfc, "subscribe", params, subscriptionQueue); err != nil {
		return nil, NewReadableError(_l("Cannot subscribe - too busy"), &err)
	}

	return storage.NewUserSubscriptions(c, pfc.UserID)
}