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) }
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) }
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) }
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 }
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) }