From 0b44c9818e746c153f2372483853a24efb67ccf9 Mon Sep 17 00:00:00 2001 From: "juozapas.cypas" Date: Wed, 12 Jun 2024 15:54:10 +0300 Subject: [PATCH 1/4] [issue-2164] created new functionality which allows to search for usernames with tags, for example "username#tag". --- sherlock/resources/data.json | 7 ++++++ sherlock/resources/data.schema.json | 1 + sherlock/sherlock.py | 39 +++++++++++++++++++++++------ sherlock/sites.py | 36 ++++++++++++++++++++++---- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/sherlock/resources/data.json b/sherlock/resources/data.json index d953802b9..f9aec3668 100644 --- a/sherlock/resources/data.json +++ b/sherlock/resources/data.json @@ -2794,5 +2794,12 @@ "url": "https://www.znanylekarz.pl/{}", "urlMain": "https://znanylekarz.pl", "username_claimed": "janusz-nowak" + }, + "LeagueOfLegends": { + "errorType": "status_code", + "url": "https://www.leagueofgraphs.com/summoner/vn/{}-<>", + "isTagRequired": true, + "urlMain": "https://www.leagueofgraphs.com", + "username_claimed": "Sophie#1911" } } diff --git a/sherlock/resources/data.schema.json b/sherlock/resources/data.schema.json index 4453500c0..b83ce590c 100644 --- a/sherlock/resources/data.schema.json +++ b/sherlock/resources/data.schema.json @@ -18,6 +18,7 @@ "username_claimed": { "type": "string" }, "regexCheck": { "type": "string" }, "isNSFW": { "type": "boolean" }, + "isTagRequired": { "type": "boolean"}, "headers": { "type": "object" }, "request_payload": { "type": "object" }, "__comment__": { diff --git a/sherlock/sherlock.py b/sherlock/sherlock.py index 4b7a27988..37893b78e 100644 --- a/sherlock/sherlock.py +++ b/sherlock/sherlock.py @@ -137,13 +137,19 @@ def get_response(request_future, error_type, social_network): return response, error_context, exception_text -def interpolate_string(input_object, username): +def interpolate_string(input_object, username, has_tag): if isinstance(input_object, str): + if has_tag and '#' in username: + username, tag = username.split('#') + input_object = input_object.replace("<>", tag) + elif has_tag: + print("Flag --tag was set, but the tag wasn't provided or was provided in an incorrect format. Please use " + "'username#tag'") return input_object.replace("{}", username) elif isinstance(input_object, dict): - return {k: interpolate_string(v, username) for k, v in input_object.items()} + return {k: interpolate_string(v, username, has_tag) for k, v in input_object.items()} elif isinstance(input_object, list): - return [interpolate_string(i, username) for i in input_object] + return [interpolate_string(i, username, has_tag) for i in input_object] return input_object @@ -168,6 +174,7 @@ def sherlock( username, site_data, query_notify: QueryNotify, + has_tag: bool = False, tor: bool = False, unique_tor: bool = False, proxy=None, @@ -254,7 +261,7 @@ def sherlock( headers.update(net_info["headers"]) # URL of user on site (if it exists) - url = interpolate_string(net_info["url"], username.replace(' ', '%20')) + url = interpolate_string(net_info["url"], username.replace(' ', '%20'), has_tag) # Don't make request if username is invalid for the site regex_check = net_info.get("regexCheck") @@ -288,7 +295,7 @@ def sherlock( raise RuntimeError(f"Unsupported request_method for {url}") if request_payload is not None: - request_payload = interpolate_string(request_payload, username) + request_payload = interpolate_string(request_payload, username, has_tag) if url_probe is None: # Probe URL is normal one seen by people out on the web. @@ -296,7 +303,7 @@ def sherlock( else: # There is a special URL for probing existence separate # from where the user profile normally can be found. - url_probe = interpolate_string(url_probe, username) + url_probe = interpolate_string(url_probe, username, has_tag) if request is None: if net_info["errorType"] == "status_code": @@ -666,6 +673,15 @@ def main(): help="Include checking of NSFW sites from default list.", ) + parser.add_argument( + "--tag", + action="store_true", + dest="tag", + default=False, + help="Search for a user name including a user tag (e.g. League of Legends, Valorant). " + "Username has to be entered in format 'username#tag'." + ) + args = parser.parse_args() # If the user presses CTRL-C, exit gracefully without throwing errors @@ -737,6 +753,11 @@ def main(): if not args.nsfw: sites.remove_nsfw_sites(do_not_remove=args.site_list) + if args.tag: + sites.filter_websites_based_on_tag(args.site_list, tag_required=True) + else: + sites.filter_websites_based_on_tag(args.site_list, tag_required=False) + # Create original dictionary from SitesInformation() object. # Eventually, the rest of the code will be updated to use the new object # directly, but this will glue the two pieces together. @@ -760,7 +781,10 @@ def main(): site_missing.append(f"'{site}'") if site_missing: - print(f"Error: Desired sites not found: {', '.join(site_missing)}.") + if args.tag: + print(f"Error: '--tag' flag was set, but {', '.join(site_missing)} usernames don't have tags.") + else: + print(f"Error: Desired sites not found: {', '.join(site_missing)}.") if not site_data: sys.exit(1) @@ -783,6 +807,7 @@ def main(): username, site_data, query_notify, + args.tag, tor=args.tor, unique_tor=args.unique_tor, proxy=args.proxy, diff --git a/sherlock/sites.py b/sherlock/sites.py index 112b6d023..15cd7fab8 100644 --- a/sherlock/sites.py +++ b/sherlock/sites.py @@ -9,7 +9,7 @@ class SiteInformation: def __init__(self, name, url_home, url_username_format, username_claimed, - information, is_nsfw, username_unclaimed=secrets.token_urlsafe(10)): + information, is_nsfw, is_tag_required, username_unclaimed=secrets.token_urlsafe(10)): """Create Site Information Object. Contains information about a specific website. @@ -55,6 +55,7 @@ def __init__(self, name, url_home, url_username_format, username_claimed, self.username_unclaimed = secrets.token_urlsafe(32) self.information = information self.is_nsfw = is_nsfw + self.is_tag_required = is_tag_required return @@ -67,7 +68,7 @@ def __str__(self): Return Value: Nicely formatted string to get information about this object. """ - + return f"{self.name} ({self.url_home})" @@ -152,7 +153,7 @@ def __init__(self, data_file_path=None): raise FileNotFoundError(f"Problem while attempting to access " f"data file '{data_file_path}'." ) - + site_data.pop('$schema', None) self.sites = {} @@ -167,7 +168,8 @@ def __init__(self, data_file_path=None): site_data[site_name]["url"], site_data[site_name]["username_claimed"], site_data[site_name], - site_data[site_name].get("isNSFW",False) + site_data[site_name].get("isNSFW", False), + site_data[site_name].get("isTagRequired", False) ) except KeyError as error: @@ -179,6 +181,30 @@ def __init__(self, data_file_path=None): return + def filter_websites_based_on_tag(self, site_list, tag_required): + """ + Filter websites based on '--tag' flag, if it's provided, the result is a list + of websites that have isTagRequired set to True, and if '--tag' is not provided, + the result is a list of all websites that don't have isTagRequired set to True. + + Keyword Arguments: + self -- This object. + site_list -- sites provided with '--site' flag + tag_required -- boolean value, True if '--tag' flag is provided + + Return Value: + None + """ + sites_requiring_tag = set(site for site in self.sites if self.sites[site].is_tag_required) + if not tag_required and sites_requiring_tag and site_list: + print("Some websites require a tag, but the tag flag is not set.") + filtered_sites = {} + for site in self.sites: + if (tag_required and site in sites_requiring_tag) or \ + (not tag_required and site not in sites_requiring_tag): + filtered_sites[site] = self.sites[site] + self.sites = filtered_sites + def remove_nsfw_sites(self, do_not_remove: list = []): """ Remove NSFW sites from the sites, if isNSFW flag is true for site @@ -194,7 +220,7 @@ def remove_nsfw_sites(self, do_not_remove: list = []): for site in self.sites: if self.sites[site].is_nsfw and site.casefold() not in do_not_remove: continue - sites[site] = self.sites[site] + sites[site] = self.sites[site] self.sites = sites def site_name_list(self): From d0587759ad013157ee6a4d1b48dac468d9e086c7 Mon Sep 17 00:00:00 2001 From: "juozapas.cypas" Date: Wed, 12 Jun 2024 18:04:59 +0300 Subject: [PATCH 2/4] [issue-2164] fixed a bug when username entered without a tag but --tag flag set would print an error many times instead of one --- sherlock/sherlock.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sherlock/sherlock.py b/sherlock/sherlock.py index 37893b78e..81c4a9c38 100644 --- a/sherlock/sherlock.py +++ b/sherlock/sherlock.py @@ -142,9 +142,6 @@ def interpolate_string(input_object, username, has_tag): if has_tag and '#' in username: username, tag = username.split('#') input_object = input_object.replace("<>", tag) - elif has_tag: - print("Flag --tag was set, but the tag wasn't provided or was provided in an incorrect format. Please use " - "'username#tag'") return input_object.replace("{}", username) elif isinstance(input_object, dict): return {k: interpolate_string(v, username, has_tag) for k, v in input_object.items()} @@ -260,6 +257,11 @@ def sherlock( # Override/append any extra headers required by a given site. headers.update(net_info["headers"]) + # if --tag flag is set but username doesn't contain tag, no need to make any requests + if has_tag and '#' not in username: + print("Flag --tag was set, but the tag wasn't provided. Please use " + "'username#tag' format") + return results_total # URL of user on site (if it exists) url = interpolate_string(net_info["url"], username.replace(' ', '%20'), has_tag) From c8850d7efedb53ba8fd7fa29f3b4344445923b41 Mon Sep 17 00:00:00 2001 From: "juozapas.cypas" Date: Wed, 12 Jun 2024 18:05:34 +0300 Subject: [PATCH 3/4] [issue-2164] added league of legends websites in different regions, with --tag flag functionality --- sherlock/resources/data.json | 70 ++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/sherlock/resources/data.json b/sherlock/resources/data.json index f9aec3668..6c612d728 100644 --- a/sherlock/resources/data.json +++ b/sherlock/resources/data.json @@ -1256,6 +1256,69 @@ "urlMain": "https://launchpad.net/", "username_claimed": "blue" }, + "LoLKr": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/kr/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "NS Callme#KR1" + }, + "LoLEune": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/eune/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "NotPurple#EUNE" + }, + "LoLEuw": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/euw/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "KC NEXT ADKING#EUW" + }, + "LoLNa": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/na/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "Sheiden#0001" + }, + "LoLVn": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/vn/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "Shirou#2K5" + }, + "LoLBr": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/br/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "frosty#KR3" + }, + "LoLTr": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/tr/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "Hide on bush#MBM0" + }, + "LoLJp": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/jp/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "Ninja of Ninjas#JP1" + }, + "LoLOce": { + "errorType": "status_code", + "isTagRequired": true, + "url": "https://www.leagueofgraphs.com/summoner/oce/{}-<>", + "urlMain": "https://www.leagueofgraphs.com/", + "username_claimed": "Stop here#OCE" + }, "LeetCode": { "errorType": "status_code", "url": "https://leetcode.com/{}", @@ -2794,12 +2857,5 @@ "url": "https://www.znanylekarz.pl/{}", "urlMain": "https://znanylekarz.pl", "username_claimed": "janusz-nowak" - }, - "LeagueOfLegends": { - "errorType": "status_code", - "url": "https://www.leagueofgraphs.com/summoner/vn/{}-<>", - "isTagRequired": true, - "urlMain": "https://www.leagueofgraphs.com", - "username_claimed": "Sophie#1911" } } From 899026c67759861f5f1388f324b27ae9fd0e13af Mon Sep 17 00:00:00 2001 From: "juozapas.cypas" Date: Wed, 12 Jun 2024 18:08:00 +0300 Subject: [PATCH 4/4] [issue-2164] added league of legends websites in different regions, with --tag flag functionality (1) --- sherlock/resources/data.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sherlock/resources/data.json b/sherlock/resources/data.json index 6c612d728..c0ad9db1f 100644 --- a/sherlock/resources/data.json +++ b/sherlock/resources/data.json @@ -1275,7 +1275,7 @@ "isTagRequired": true, "url": "https://www.leagueofgraphs.com/summoner/euw/{}-<>", "urlMain": "https://www.leagueofgraphs.com/", - "username_claimed": "KC NEXT ADKING#EUW" + "username_claimed": "normalus bahuras#EUW" }, "LoLNa": { "errorType": "status_code",