diff --git a/ofscraper/classes/models.py b/ofscraper/classes/models.py index 0d7f1ff4e..dfc32b5a5 100644 --- a/ofscraper/classes/models.py +++ b/ofscraper/classes/models.py @@ -10,6 +10,11 @@ class Model: def __init__(self, model): self._model = model + """ + Pure properties + Should Return original JSON value or None + """ + # All media return from API dict @property def model(self): @@ -88,7 +93,7 @@ def expired(self): return None elif not self.subscribed_data.get("expiredAt"): return None - return arrow.get(self.subscribed_data.get("expiredAt")).format(FORMAT) + return self.subscribed_data.get("expiredAt") @property def final_expired(self): @@ -96,44 +101,48 @@ def final_expired(self): return 0 return self.expired + """ + Best values to retrive depends on how many times subscribed + + """ + @property def subscribed(self): if not self.subscribed_data: return None - elif ( - not self.subscribed_data.get("subscribes") - or len(self.subscribed_data.get("subscribes")) == 0 - ): - return None + elif len(self.subscribed_data.get("subscribes", [])) == 0: + return self.subscribed_data.get("subscribeAt") return self.subscribed_data.get("subscribes")[0].get("startDate") - @property - def final_subscribed(self): - if self.subscribed: - return arrow.get(self.subscribed).float_timestamp - else: - return 0 - @property def renewed(self): if not self.subscribed_data: return None elif not self.subscribed_data.get("renewedAt"): return None - return arrow.get(self.subscribed_data.get("renewedAt")).format(FORMAT) + return self.subscribed_data.get("renewedAt") + + """ + helper properties for filtering/sorting etc + """ @property def active(self): - if not self.subscribed_data or self.subscribed_expired_date: + if self.subscribed_data and self.subscribed_data["status"] == "Set to Expire": return False - elif self.subscribed_data and self.subscribed_data["status"] == "Set to Expire": + if not self.renewed: + return False + return True + + @property + def account_access(self): + if self.subscribed_data and self.subscribed_data["status"] == "Set to Expire": return True - return ( - arrow.get( - (self.subscribed_data or self.subscribed_expired_date).get("expiredAt") - ) - > DATE_NOW - ) + if self.renewed: + return True + if not self.subscribed: + return False + return arrow.get(self.expired) > args_.getargs().date_now @property def last_seen(self): @@ -185,6 +194,31 @@ def final_promo_price(self): @property def final_last_seen(self): if not self.last_seen: - return args_.getargs().date_now.float_timestamp + constants.DAY_SECONDS + return arrow.now() else: - return arrow.get(self.last_seen).float_timestamp + return arrow.get(self.last_seen) + + @property + def renewed_string(self): + if not self.renewed: + return None + return arrow.get(self.renewed).format(FORMAT) + + @property + def subscribed_string(self): + if not self.subscribed: + return None + return arrow.get(self.subscribed).format(FORMAT) + + @property + def expired_string(self): + if not self.expired: + return None + return arrow.get(self.expired).format(FORMAT) + + @property + def final_subscribed(self): + if self.subscribed: + return arrow.get(self.subscribed).float_timestamp + else: + return 0 diff --git a/ofscraper/constants.py b/ofscraper/constants.py index 3ea261788..645b8c33a 100644 --- a/ofscraper/constants.py +++ b/ofscraper/constants.py @@ -10,8 +10,6 @@ import os import pathlib -import arrow - preferences = "pref_config.py" configPath = ".config/ofscraper" configFile = "config.json" diff --git a/ofscraper/filters/models/flags.py b/ofscraper/filters/models/flags.py index 5a7367951..dcc736dd7 100644 --- a/ofscraper/filters/models/flags.py +++ b/ofscraper/filters/models/flags.py @@ -31,5 +31,30 @@ def promoFilterHelper(filterusername): filter(lambda x: x.lowest_promo_all is None, filterusername) ) log.debug(f"All Promo Flag No Count: {len(filterusername)}") + log.debug(f"Last Seen Flag: {args_.getargs().last_seen}") + if args_.getargs().last_seen == "yes": + filterusername = list(filter(lambda x: x.last_seen is not None, filterusername)) + log.debug(f"Last Seen Flag Yes Count: {len(filterusername)}") + + elif args_.getargs().last_seen == "no": + filterusername = list(filter(lambda x: x.last_seen is None, filterusername)) + log.debug(f"Last Seen Flag No Count: {len(filterusername)}") + log.debug(f"Last Seen Flag: {args_.getargs().last_seen}") + if args_.getargs().free_trail == "yes": + filterusername = list( + filter( + lambda x: (x.final_current_price == 0 and x.final_regular_price > 0), + filterusername, + ) + ) + log.debug(f"Free Trail Flag Yes Count: {len(filterusername)}") + elif args_.getargs().free_trail == "no": + filterusername = list( + filter( + lambda x: (x.final_current_price > 0 or x.final_regular_price == 0), + filterusername, + ) + ) + log.debug(f"Free Trail Flag No Count: {len(filterusername)}") return filterusername diff --git a/ofscraper/filters/models/other.py b/ofscraper/filters/models/other.py new file mode 100644 index 000000000..3f8b760eb --- /dev/null +++ b/ofscraper/filters/models/other.py @@ -0,0 +1,40 @@ +""" +other filters +""" + +import logging + +import ofscraper.utils.args as args_ + + +def otherFilters(filterusername): + log = logging.getLogger("shared") + + log.debug(f"Last Seen After Filter: {args_.getargs().last_seen_after}") + if args_.getargs().last_seen_after: + filterusername = list( + filter( + lambda x: x.final_last_seen >= args_.getargs().last_seen_after, + filterusername, + ) + ) + log.debug(f"last seen after username count: {len(filterusername)}") + log.debug(f"Last Seen Before Filter: {args_.getargs().last_seen_before}") + if args_.getargs().last_seen_before: + filterusername = list( + filter( + lambda x: x.final_last_seen <= args_.getargs().last_seen_before, + filterusername, + ) + ) + log.debug(f"last seen befpre username count: {len(filterusername)}") + log.debug(f"Excluded usernames: {args_.getargs().excluded_username}") + if len(args_.getargs().excluded_username) > 0: + filterusername = list( + filter( + lambda x: x.name not in args_.getargs().excluded_username, + filterusername, + ) + ) + + return filterusername diff --git a/ofscraper/filters/models/price.py b/ofscraper/filters/models/price.py index 81a587db2..668328e6d 100644 --- a/ofscraper/filters/models/price.py +++ b/ofscraper/filters/models/price.py @@ -47,7 +47,9 @@ def pricePaidFreeFilterHelper(filterusername): filterusername = list(filter(lambda x: x.final_regular_price, filterusername)) log.debug(f"paid regular price filter username count: {len(filterusername)}") elif args_.getargs().regular_price == "free": - filterusername = list(filter(lambda x: x.final_regular_price), filterusername) + filterusername = list( + filter(lambda x: x.final_regular_price == 0, filterusername) + ) log.debug(f"free regular price filter username count: {len(filterusername)}") log.debug(f"Promo Price Filter: {args_.getargs().promo_price}") if args_.getargs().promo_price == "paid": diff --git a/ofscraper/filters/models/selector.py b/ofscraper/filters/models/selector.py index fb1b9efde..af090e987 100644 --- a/ofscraper/filters/models/selector.py +++ b/ofscraper/filters/models/selector.py @@ -3,6 +3,7 @@ import ofscraper.constants as constants import ofscraper.filters.models.flags as flags +import ofscraper.filters.models.other as other import ofscraper.filters.models.price as price import ofscraper.filters.models.retriver as retriver import ofscraper.filters.models.sort as sort @@ -88,12 +89,7 @@ def filterNSort(usernames): filterusername = subtype.subType(usernames) filterusername = price.pricePaidFreeFilterHelper(filterusername) filterusername = flags.promoFilterHelper(filterusername) - filterusername = list( - filter( - lambda x: x.name not in args_.getargs().excluded_username, - filterusername, - ) - ) + filterusername = other.otherFilters(filterusername) log.debug(f"final username count with all filters: {len(filterusername)}") # give log time to process @@ -106,8 +102,10 @@ def filterNSort(usernames): Sub Status: {args_.getargs().sub_status or 'No Filter'} Renewal Status: {args_.getargs().renewal or 'No Filter'} -Account Type: {args_.getargs().account_type or 'No Filter'} - +Promo Price Filter: {args_.getargs().promo_price or 'No Filter'} +Current Price Filter: {args_.getargs().current_price or 'No Filter'} +Current Price Filter: {args_.getargs().current_price or 'No Filter'} +Renewal Price Filter: {args_.getargs().renewal_price or 'No Filter'} """ ) diff --git a/ofscraper/filters/models/subtype.py b/ofscraper/filters/models/subtype.py index cc6bdaaba..2a99346e3 100644 --- a/ofscraper/filters/models/subtype.py +++ b/ofscraper/filters/models/subtype.py @@ -7,17 +7,17 @@ def subType(filterusername): log = logging.getLogger("shared") log.debug(f"Renewal: {args_.getargs().renewal}") if args_.getargs().renewal == "active": - filterusername = list(filter(lambda x: x.renewed is not None, filterusername)) + filterusername = list(filter(lambda x: x.active, filterusername)) log.debug(f"active renewal filter username count: {len(filterusername)}") elif args_.getargs().renewal == "disabled": - filterusername = list(filter(lambda x: x.renewed is None, filterusername)) + filterusername = list(filter(lambda x: not x.active, filterusername)) log.debug(f"disabled renewal filter username count: {len(filterusername)}") log.debug(f"Sub Status: {args_.getargs().sub_status}") if args_.getargs().sub_status == "active": - filterusername = list(filter(lambda x: x.active, filterusername)) + filterusername = list(filter(lambda x: x.account_access, filterusername)) log.debug(f"active subscribtion filter username count: {len(filterusername)}") elif args_.getargs().sub_status == "expired": - filterusername = list(filter(lambda x: x.active is None, filterusername)) + filterusername = list(filter(lambda x: not x.account_access, filterusername)) log.debug(f"expired subscribtion filter username count: {len(filterusername)}") return filterusername diff --git a/ofscraper/prompts/model_helpers.py b/ofscraper/prompts/model_helpers.py index 76717c3bb..ed0df0bf3 100644 --- a/ofscraper/prompts/model_helpers.py +++ b/ofscraper/prompts/model_helpers.py @@ -9,28 +9,33 @@ def model_selectorHelper(count, x): return Choice( x, - name=f"{count+1}: {x.name} => subscribed date: {generalDated(x.subscribed)}{renewHelper(x)}{lastSeenHelper(x)} | {getPriceHelper(x)}", + name=f"{count+1}: {x.name} => subscribed date: {generalDated(x.subscribed_string)}{renewHelper(x)}{lastSeenHelper(x)} | {getPriceHelper(x)}", ) def renewHelper(x): - if args_.getargs().sort != "expired": + if args_.getargs().sort != "expired" and args_.getargs().renewal is None: return "" return ( " | end/renewed date: N/A" - if x.renewed or x.expired is None - else f" | end/renewed date: {arrow.get(x.renewed or x.expired).format('YYYY-MM-DD: HH:mm')}" + if (x.renewed_string or x.expired_string) is None + else f" | end/renewed date: {arrow.get(x.renewed_string or x.expired_string).format('YYYY-MM-DD: HH:mm')}" ) def generalDated(value): if value is None: return "N/A" - return arrow.get(value).format("YYYY-MM-DD: HH:mm") + return value def lastSeenHelper(x): - if args_.getargs().sort != "last-seen": + if ( + args_.getargs().sort != "last-seen" + and not args_.getargs().last_seen + and not args_.getargs().last_seen_after + and not args_.getargs().last_seen_before + ): return "" return ( " | last seen: Hidden" @@ -40,13 +45,23 @@ def lastSeenHelper(x): def getPriceHelper(x): - value = re.sub( - "-", - "_", - args_.getargs().sort - if args_.getargs().sort - in {"current-price", "renewal-price", "regular-price", "promo-price"} - else "current-price", - ).replace("-", "_") - key = f"final_{value}" - return f"{value}: {getattr(x, key)}" + value = None + value2 = None + if args_.getargs().sort in { + "current-price", + "renewal-price", + "regular-price", + "promo-price", + }: + value = re.sub("-", "_", args_.getargs().sort).replace("-", "_") + if args_.getargs().promo_price: + value2 = "promo_price" + elif args_.getargs().regular_price: + value2 = "regular_price" + elif args_.getargs().renewal_price: + value2 = "renewal_price" + elif args_.getargs().current_price: + value2 = "current_price" + final_value = value or value2 or "current_price" + key = f"final_{final_value}" + return f"{final_value }: {getattr(x, key)}" diff --git a/ofscraper/prompts/prompts.py b/ofscraper/prompts/prompts.py index 42de6efda..74f433a24 100644 --- a/ofscraper/prompts/prompts.py +++ b/ofscraper/prompts/prompts.py @@ -935,8 +935,8 @@ def funct2(prompt_): f""" Name: [bold blue]{selected.name}[/bold blue] ID: [bold blue]{selected.id}[/bold blue] - Renewed Date: [bold blue]{selected.renewed}[/bold blue] - Subscribed Date: [bold blue]{selected.subscribed}[/bold blue] + Renewed Date: [bold blue]{selected.renewed_string}[/bold blue] + Subscribed Date: [bold blue]{selected.subscribed_string}[/bold blue] Expired Date: [bold blue]{selected.expired}[/bold blue] Last Seen: {selected.last_seen} Original Sub Price: [bold blue]{selected.sub_price}[/bold blue] [Current Subscription Price] @@ -1017,6 +1017,28 @@ def modify_filters_prompt(args): Choice(False, "Both"), ], }, + { + "type": "list", + "name": "last-seen", + "default": False, + "message": "Filter Accounts By whether the account by the visability of last seen", + "choices": [ + Choice("yes", "Last seen is present"), + Choice("no", "Last seen is hidden"), + Choice(False, "Both"), + ], + }, + { + "type": "list", + "name": "free-trail", + "default": False, + "message": "Filter Accounts By whether the account is a free trail", + "choices": [ + Choice("yes", "Free Trail only"), + Choice("no", "Paid and always free accounts"), + Choice(False, "Both"), + ], + }, { "type": "list", "name": "subscription", @@ -1093,6 +1115,8 @@ def modify_filters_prompt(args): args.regular_price = answer["regular"] args.renewal_price = answer["future"] args.promo_price = answer["promo-price"] + args.free_trail = answer["free-trail"] + args.last_seen = answer["last-seen"] return args diff --git a/ofscraper/utils/args.py b/ofscraper/utils/args.py index 39b85520d..de33140fd 100644 --- a/ofscraper/utils/args.py +++ b/ofscraper/utils/args.py @@ -328,6 +328,43 @@ def create_parser(input=None): choices=["paid", "free"], ) + filters.add_argument( + "-lsb", + "--last-seen-before", + help="Filter Accounts by last seen being before the given date", + default=False, + required=False, + type=arrow_helper, + ) + filters.add_argument( + "-lsa", + "--last-seen-after", + help="Filter Accounts by last seen being before the given date", + default=False, + required=False, + type=arrow_helper, + ) + + filters.add_argument( + "-ls", + "--last-seen", + help="Filter Accounts by whether last seen is visible", + default=False, + required=False, + type=str.lower, + choices=["yes", "no"], + ) + + filters.add_argument( + "-frt", + "--free-trail", + help="Filter Accounts by whether last seen is visible", + default=False, + required=False, + type=str.lower, + choices=["yes", "no"], + ) + filters.add_argument( "-pp", "--promo-price",