Amazon Category Selector

Automatically redirects to the daily sales page with preselected categories

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Amazon Category Selector
// @namespace    https://lewisch.io/
// @version      1.0
// @description  Automatically redirects to the daily sales page with preselected categories
// @author       Thomas Lewisch
// @match        *.amazon.de/gp/angebote*
// @require      https://code.jquery.com/jquery-2.2.0.min.js
// @grant        none
// ==/UserScript==
/* jshint -W097 */
'use strict';

var CategorySelector = function(options) {
    this.options = options || {};

    this.defaults = {
        url: 'http://www.amazon.de/gp/angebote', // the base url for daily offers,
        sortOrder: 'BY_SCORE', // the sort order for displaying the offers
        categories: [  // the category-ids to auto-select
            340843031, // pc
            300992,    // games
            284266,    // movies
            562066,    // electronics
        ],
        keys: {                               // the keys to use for building the url
            base: 'gb_f_GB-SUPPLE',           // the base query string argument used by amazon
            sortOrder: 'sortOrder',           // the key for the sort order
            categories: 'enforcedCategories', // the key for the categories
        },
        concatenators: {     // the concatenators to concatenate the different parts of the url
            qs: '?',         // the concatentor for the query string
            kv: ':',         // the key-value concatenator for different arguments
            ba: '=',         // the base-arguments concatentator for the base key to the other arguments
            args: ',',       // the arguments concatentator for joining various arguments
            values: '%252C', // the concatentor for the values of a single argument
        },
        selectors: {                               // the selectors used to find the categories
            categoryContainer: '#widgetFilters',   // the selector for the category container
            activeCategories: ':checkbox:checked', // the selector for the active categories
        },
    };

    this.settings = jQuery.extend({}, this.defaults, options);
};

/**
 * starts the category selector
 *
 * @return {void}
 */
CategorySelector.prototype.run = function () {
    var self = this,
        exists = window.setInterval(function() {
            if (self.filters().length) {
                self.redirectIfNecessary();
                window.clearInterval(exists);
            }
        }, 100);
};

/**
 * redirects the browser to the filtered
 * daily offers page if necessary
 *
 * @return {void}
 */
CategorySelector.prototype.redirectIfNecessary = function () {
    if (this.hasActiveCategories()) {
        return;
    }

    window.location.replace(this.buildUrl());
};

/**
 * builds the url to redirect to
 *
 * @return {string}
 */
CategorySelector.prototype.buildUrl = function () {
    var args = [];

    if (! this.hasSettings()) {
        return this.settings.url;
    }

    if (this.hasSortOrder()) {
        args.push(this.settings.keys.sortOrder + this.settings.concatenators.kv + this.settings.sortOrder);
    }

    if (this.hasCategories()) {
        args.push(this.settings.keys.categories + this.settings.concatenators.kv + this.buildCategoryString());
    }

    return this.settings.url +
        this.settings.concatenators.qs +
        this.settings.keys.base +
        this.settings.concatenators.ba +
        args.join(this.settings.concatenators.args);
};

/**
 * gets the active categories
 *
 * @return {jQuery element|array}
 */
CategorySelector.prototype.activeCategories = function () {
    return this.filters().find(this.settings.selectors.activeCategories);
};

/**
 * checks if categories are currently active
 *
 * @return {boolean}
 */
CategorySelector.prototype.hasActiveCategories = function () {
    return this.activeCategories().length > 0;
};

/**
 * checks if settings have been supplied to
 * build a custom url and redirect
 *
 * @return {boolean}
 */
CategorySelector.prototype.hasSettings = function () {
    return this.hasSortOrder() || this.hasCategories();
};

/**
 * checks of a sort order has been supplied
 *
 * @return {boolean}
 */
CategorySelector.prototype.hasSortOrder = function () {
    return this.settings.sortOrder !== false && this.settings.sortOrder !== null;
};

/**
 * checks if categories have been supplied
 *
 * @return {boolean}
 */
CategorySelector.prototype.hasCategories = function () {
    return jQuery.isArray(this.settings.categories) && this.settings.categories.length > 0;
};

/**
 * builds the category string for the url
 *
 * @return {string}
 */
CategorySelector.prototype.buildCategoryString = function () {
    return this.settings.categories.join(this.settings.concatenators.values);
};

/**
 * gets the container element that holds the filters
 *
 * @return {jQuery element|array}
 */
CategorySelector.prototype.filters = function () {
    return jQuery(document).find(this.settings.selectors.categoryContainer);
};

/**
 * initializes a new category selector
 *
 * @param  {Object} options
 * @return {CategorySelector}
 */
CategorySelector.init = function(options) {
    var selector = new CategorySelector(options);

    selector.run();

    return selector;
};

jQuery(document).ready(function($) {
    CategorySelector.init();
});