Hello community, here is the log from the commit of package python-shodan for openSUSE:Factory checked in at 2020-11-09 13:57:52 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-shodan (Old) and /work/SRC/openSUSE:Factory/.python-shodan.new.11331 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-shodan" Mon Nov 9 13:57:52 2020 rev:25 rq:846973 version:1.24.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-shodan/python-shodan.changes 2020-09-21 17:42:29.704860549 +0200 +++ /work/SRC/openSUSE:Factory/.python-shodan.new.11331/python-shodan.changes 2020-11-09 13:59:02.831750052 +0100 @@ -1,0 +2,8 @@ +Sun Nov 1 19:33:22 UTC 2020 - Sebastian Wagner <sebix+novell....@sebix.at> + +- Update to version 1.24.0: + * use default config dir `~/.config/shodan`, but support existing installations + * Fix bug that caused extra newlines when converting `.json.gz` data file to CSV on Windows + * Fix linting error + +------------------------------------------------------------------- Old: ---- shodan-1.23.1.tar.gz New: ---- shodan-1.24.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-shodan.spec ++++++ --- /var/tmp/diff_new_pack.hakkjt/_old 2020-11-09 13:59:03.447748709 +0100 +++ /var/tmp/diff_new_pack.hakkjt/_new 2020-11-09 13:59:03.447748709 +0100 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %{!?license: %global license %doc} Name: python-shodan -Version: 1.23.1 +Version: 1.24.0 Release: 0 Summary: Python library and command-line utility for Shodan License: MIT ++++++ shodan-1.23.1.tar.gz -> shodan-1.24.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shodan-1.23.1/PKG-INFO new/shodan-1.24.0/PKG-INFO --- old/shodan-1.23.1/PKG-INFO 2020-09-08 02:40:48.000000000 +0200 +++ new/shodan-1.24.0/PKG-INFO 2020-10-12 00:55:18.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: shodan -Version: 1.23.1 +Version: 1.24.0 Summary: Python library and command-line utility for Shodan (https://developer.shodan.io) Home-page: http://github.com/achillean/shodan-python/tree/master Author: John Matherly diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shodan-1.23.1/setup.py new/shodan-1.24.0/setup.py --- old/shodan-1.23.1/setup.py 2020-09-08 02:19:46.000000000 +0200 +++ new/shodan-1.24.0/setup.py 2020-10-12 00:24:01.000000000 +0200 @@ -9,7 +9,7 @@ setup( name='shodan', - version='1.23.1', + version='1.24.0', description='Python library and command-line utility for Shodan (https://developer.shodan.io)', long_description=README, long_description_content_type='text/x-rst', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shodan-1.23.1/shodan/cli/alert.py new/shodan-1.24.0/shodan/cli/alert.py --- old/shodan-1.23.1/shodan/cli/alert.py 2020-04-06 22:06:05.000000000 +0200 +++ new/shodan-1.24.0/shodan/cli/alert.py 2020-10-12 00:48:51.000000000 +0200 @@ -1,10 +1,73 @@ import click +import csv import shodan +from collections import defaultdict from operator import itemgetter from shodan.cli.helpers import get_api_key +MAX_QUERY_LENGTH = 1000 + + +def aggregate_facet(api, networks, facets): + """Merge the results from multiple facet API queries into a single result object. + This is necessary because a user might be monitoring a lot of IPs/ networks so it doesn't fit + into a single API call. + """ + def _merge_custom_facets(lfacets, results): + for key in results['facets']: + if key not in lfacets: + lfacets[key] = defaultdict(int) + + for item in results['facets'][key]: + lfacets[key][item['value']] += item['count'] + + # We're going to create a custom facets dict where + # the key is the value of a facet. Normally the facets + # object is a list where each item has a "value" and "count" property. + tmp_facets = {} + count = 0 + + query = 'net:' + + for net in networks: + query += '{},'.format(net) + + # Start running API queries if the query length is getting long + if len(query) > MAX_QUERY_LENGTH: + results = api.count(query[:-1], facets=facets) + + _merge_custom_facets(tmp_facets, results) + count += results['total'] + query = 'net:' + + # Run any remaining search query + if query[-1] != ':': + results = api.count(query[:-1], facets=facets) + + _merge_custom_facets(tmp_facets, results) + count += results['total'] + + # Convert the internal facets structure back to the one that + # the API returns. + new_facets = {} + for facet in tmp_facets: + sorted_items = sorted(tmp_facets[facet].items(), key=itemgetter(1), reverse=True) + new_facets[facet] = [{'value': key, 'count': value} for key, value in sorted_items] + + # Make sure the facet keys exist even if there weren't any results + for facet, _ in facets: + if facet not in new_facets: + new_facets[facet] = [] + + return { + 'matches': [], + 'facets': new_facets, + 'total': count, + } + + @click.group() def alert(): """Manage the network alerts for your account""" @@ -149,6 +212,95 @@ click.echo("You haven't created any alerts yet.") +@alert.command(name='stats') +@click.option('--limit', help='The number of results to return.', default=10, type=int) +@click.option('--filename', '-O', help='Save the results in a CSV file of the provided name.', default=None) +@click.argument('facets', metavar='<facets ...>', nargs=-1) +def alert_stats(limit, filename, facets): + """Show summary information about your monitored networks""" + # Setup Shodan + key = get_api_key() + api = shodan.Shodan(key) + + # Make sure the user didn't supply an empty string + if not facets: + raise click.ClickException('No facets provided') + + facets = [(facet, limit) for facet in facets] + + # Get the list of IPs/ networks that the user is monitoring + networks = set() + try: + alerts = api.alerts() + for alert in alerts: + for tmp in alert['filters']['ip']: + networks.add(tmp) + except shodan.APIError as e: + raise click.ClickException(e.value) + + # Grab the facets the user requested + try: + results = aggregate_facet(api, networks, facets) + except shodan.APIError as e: + raise click.ClickException(e.value) + + # TODO: The below code was taken from __main__.py:stats() - we should refactor it so the code can be shared + # Print the stats tables + for facet in results['facets']: + click.echo('Top {} Results for Facet: {}'.format(len(results['facets'][facet]), facet)) + + for item in results['facets'][facet]: + # Force the value to be a string - necessary because some facet values are numbers + value = u'{}'.format(item['value']) + + click.echo(click.style(u'{:28s}'.format(value), fg='cyan'), nl=False) + click.echo(click.style(u'{:12,d}'.format(item['count']), fg='green')) + + click.echo('') + + # Create the output file if requested + fout = None + if filename: + if not filename.endswith('.csv'): + filename += '.csv' + fout = open(filename, 'w') + writer = csv.writer(fout, dialect=csv.excel) + + # Write the header that contains the facets + row = [] + for facet in results['facets']: + row.append(facet) + row.append('') + writer.writerow(row) + + # Every facet has 2 columns (key, value) + counter = 0 + has_items = True + while has_items: + # pylint: disable=W0612 + row = ['' for i in range(len(results['facets']) * 2)] + + pos = 0 + has_items = False + for facet in results['facets']: + values = results['facets'][facet] + + # Add the values for the facet into the current row + if len(values) > counter: + has_items = True + row[pos] = values[counter]['value'] + row[pos + 1] = values[counter]['count'] + + pos += 2 + + # Write out the row + if has_items: + writer.writerow(row) + + # Move to the next row of values + counter += 1 + + @alert.command(name='remove') @click.argument('alert_id', metavar='<alert ID>') def alert_remove(alert_id): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shodan-1.23.1/shodan/cli/settings.py new/shodan-1.24.0/shodan/cli/settings.py --- old/shodan-1.23.1/shodan/cli/settings.py 2020-09-08 02:37:18.000000000 +0200 +++ new/shodan-1.24.0/shodan/cli/settings.py 2020-10-12 00:24:28.000000000 +0200 @@ -4,7 +4,7 @@ if path.exists(path.expanduser("~/.shodan")): SHODAN_CONFIG_DIR = '~/.shodan/' else: - SHODAN_CONFIG_DIR="~/.config/shodan/" + SHODAN_CONFIG_DIR = "~/.config/shodan/" COLORIZE_FIELDS = { 'ip_str': 'green', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/shodan-1.23.1/shodan.egg-info/PKG-INFO new/shodan-1.24.0/shodan.egg-info/PKG-INFO --- old/shodan-1.23.1/shodan.egg-info/PKG-INFO 2020-09-08 02:40:48.000000000 +0200 +++ new/shodan-1.24.0/shodan.egg-info/PKG-INFO 2020-10-12 00:55:18.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: shodan -Version: 1.23.1 +Version: 1.24.0 Summary: Python library and command-line utility for Shodan (https://developer.shodan.io) Home-page: http://github.com/achillean/shodan-python/tree/master Author: John Matherly