#!/usr/bin/env python

# $Id$
#
# Copyright (C) 2009--2013  Internet Systems Consortium ("ISC")
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# Portions copyright (C) 2007--2008  American Registry for Internet Numbers ("ARIN")
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS.  IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.

__doc__ = """
Command line IR back-end control program for rpkid and pubd.
"""

import sys
import getopt
import textwrap
import rpki.left_right
import rpki.http
import rpki.x509
import rpki.config
import rpki.log
import rpki.publication
import rpki.async

pem_out = None

class UsageWrapper(textwrap.TextWrapper):
  """
  Call interface around Python textwrap.Textwrapper class.
  """

  def __call__(self, *args):
    """
    Format arguments, with TextWrapper indentation.
    """
    return self.fill(textwrap.dedent(" ".join(args)))

usage_fill = UsageWrapper(subsequent_indent = " " * 4)

class reply_elt_mixin(object):
  """
  Protocol mix-in for printout of reply PDUs.
  """

  is_cmd = False

  def client_reply_decode(self):
    pass

  def client_reply_show(self):
    print self.element_name
    for i in self.attributes + self.elements:
      if getattr(self, i) is not None:
        print "  %s: %s" % (i, getattr(self, i))

class cmd_elt_mixin(reply_elt_mixin):
  """
  Protocol mix-in for command line client element PDUs.
  """

  is_cmd = True

  ## @var excludes
  # XML attributes and elements that should not be allowed as command
  # line arguments.
  excludes = ()

  @classmethod
  def usage(cls):
    """
    Generate usage message for this PDU.
    """
    args = " ".join("--" + x + "=" for x in cls.attributes + cls.elements if x not in cls.excludes)
    bools = " ".join("--" + x for x in cls.booleans)
    if args and bools:
      return args + " " + bools
    else:
      return args or bools

  def client_getopt(self, argv):
    """
    Parse options for this class.
    """
    # pylint: disable=W0621
    opts, argv = getopt.getopt(argv, "", [x + "=" for x in self.attributes + self.elements if x not in self.excludes] + list(self.booleans))
    for o, a in opts:
      o = o[2:]
      handler = getattr(self, "client_query_" + o, None)
      if handler is not None:
        handler(a)
      elif o in self.booleans:
        setattr(self, o, True)
      else:
        assert o in self.attributes
        setattr(self, o, a)
    return argv

  def client_query_bpki_cert(self, arg):
    """
    Special handler for --bpki_cert option.
    """
    self.bpki_cert = rpki.x509.X509(Auto_file = arg)

  def client_query_glue(self, arg):
    """
    Special handler for --bpki_glue option.
    """
    self.bpki_glue = rpki.x509.X509(Auto_file = arg)

  def client_query_bpki_cms_cert(self, arg):
    """
    Special handler for --bpki_cms_cert option.
    """
    self.bpki_cms_cert = rpki.x509.X509(Auto_file = arg)

  def client_query_cms_glue(self, arg):
    """
    Special handler for --bpki_cms_glue option.
    """
    self.bpki_cms_glue = rpki.x509.X509(Auto_file = arg)

class cmd_msg_mixin(object):
  """
  Protocol mix-in for command line client message PDUs.
  """

  @classmethod
  def usage(cls):
    """
    Generate usage message for this PDU.
    """
    for k, v in cls.pdus.items():
      if v.is_cmd:
        print usage_fill(k, v.usage())

# left-right protcol

class left_right_msg(cmd_msg_mixin, rpki.left_right.msg):

  class self_elt(cmd_elt_mixin, rpki.left_right.self_elt):
    pass

  class bsc_elt(cmd_elt_mixin, rpki.left_right.bsc_elt):

    excludes = ("pkcs10_request",)

    def client_query_signing_cert(self, arg):
      """--signing_cert option."""
      self.signing_cert = rpki.x509.X509(Auto_file = arg)

    def client_query_signing_cert_crl(self, arg):
      """--signing_cert_crl option."""
      self.signing_cert_crl = rpki.x509.CRL(Auto_file = arg)

    def client_reply_decode(self):
      global pem_out
      if pem_out is not None and self.pkcs10_request is not None:
        if isinstance(pem_out, str):
          pem_out = open(pem_out, "w")
        pem_out.write(self.pkcs10_request.get_PEM())

  class parent_elt(cmd_elt_mixin, rpki.left_right.parent_elt):
    pass

  class child_elt(cmd_elt_mixin, rpki.left_right.child_elt):
    pass

  class repository_elt(cmd_elt_mixin, rpki.left_right.repository_elt):
    pass

  class list_published_objects_elt(cmd_elt_mixin, rpki.left_right.list_published_objects_elt):
    excludes = ("uri",)

  class list_received_resources_elt(cmd_elt_mixin, rpki.left_right.list_received_resources_elt):
    excludes = ("parent_handle", "notBefore", "notAfter", "uri", "sia_uri", "aia_uri", "asn", "ipv4", "ipv6")

  class report_error_elt(reply_elt_mixin, rpki.left_right.report_error_elt):
    pass

  pdus = dict((x.element_name, x)
              for x in (self_elt, bsc_elt, parent_elt, child_elt, repository_elt,
                        list_published_objects_elt, list_received_resources_elt, report_error_elt))

class left_right_sax_handler(rpki.left_right.sax_handler):
  pdu = left_right_msg

class left_right_cms_msg(rpki.left_right.cms_msg):
  saxif<style>pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888 } /* Comment */
.highlight .err { color: #A61717; background-color: #E3D2D2 } /* Error */
.highlight .k { color: #080; font-weight: bold } /* Keyword */
.highlight .ch { color: #888 } /* Comment.Hashbang */
.highlight .cm { color: #888 } /* Comment.Multiline */
.highlight .cp { color: #C00; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888 } /* Comment.Single */
.highlight .cs { color: #C00; font-weight: bold; background-color: #FFF0F0 } /* Comment.Special */
.highlight .gd { color: #000; background-color: #FDD } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #A00 } /* Generic.Error */
.highlight .gh { color: #333 } /* Generic.Heading */
.highlight .gi { color: #000; background-color: #DFD } /* Generic.Inserted */
.highlight .go { color: #888 } /* Generic.Output */
.highlight .gp { color: #555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666 } /* Generic.Subheading */
.highlight .gt { color: #A00 } /* Generic.Traceback */
.highlight .kc { color: #080; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #080; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #080; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #080 } /* Keyword.Pseudo */
.highlight .kr { color: #080; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #00D; font-weight: bold } /* Literal.Number */
.highlight .s { color: #D20; background-color: #FFF0F0 } /* Literal.String */
.highlight .na { color: #369 } /* Name.Attribute */
.highlight .nb { color: #038 } /* Name.Builtin */
.highlight .nc { color: #B06; font-weight: bold } /* Name.Class */
.highlight .no { color: #036; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555 } /* Name.Decorator */
.highlight .ne { color: #B06; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #06B; font-weight: bold } /* Name.Function */
.highlight .nl { color: #369; font-style: italic } /* Name.Label */
.highlight .nn { color: #B06; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #369; font-weight: bold } /* Name.Property */
.highlight .nt { color: #B06; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #369 } /* Name.Variable */
.highlight .ow { color: #080 } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #00D; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #00D; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #00D; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #00D; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #00D; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #D20; background-color: #FFF0F0 } /* Literal.String.Affix */
.highlight .sb { color: #D20; background-color: #FFF0F0 } /* Literal.String.Backtick */
.highlight .sc { color: #D20; background-color: #FFF0F0 } /* Literal.String.Char */
.highlight .dl { color: #D20; background-color: #FFF0F0 } /* Literal.String.Delimiter */
.highlight .sd { color: #D20; background-color: #FFF0F0 } /* Literal.String.Doc */
.highlight .s2 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Double */
.highlight .se { color: #04D; background-color: #FFF0F0 } /* Literal.String.Escape */
.highlight .sh { color: #D20; background-color: #FFF0F0 } /* Literal.String.Heredoc */
.highlight .si { color: #33B; background-color: #FFF0F0 } /* Literal.String.Interpol */
.highlight .sx { color: #2B2; background-color: #F0FFF0 } /* Literal.String.Other */
.highlight .sr { color: #080; background-color: #FFF0FF } /* Literal.String.Regex */
.highlight .s1 { color: #D20; background-color: #FFF0F0 } /* Literal.String.Single */
.highlight .ss { color: #A60; background-color: #FFF0F0 } /* Literal.String.Symbol */
.highlight .bp { color: #038 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #06B; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #369 } /* Name.Variable.Class */
.highlight .vg { color: #D70 } /* Name.Variable.Global */
.highlight .vi { color: #33B } /* Name.Variable.Instance */
.highlight .vm { color: #369 } /* Name.Variable.Magic */
.highlight .il { color: #00D; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="c1"># $Id$</span>
<span class="c1"># </span>
<span class="c1"># Copyright (C) 2010  Internet Systems Consortium (&quot;ISC&quot;)</span>
<span class="c1"># </span>
<span class="c1"># Permission to use, copy, modify, and distribute this software for any</span>
<span class="c1"># purpose with or without fee is hereby granted, provided that the above</span>
<span class="c1"># copyright notice and this permission notice appear in all copies.</span>
<span class="c1"># </span>
<span class="c1"># THE SOFTWARE IS PROVIDED &quot;AS IS&quot; AND ISC DISCLAIMS ALL WARRANTIES WITH</span>
<span class="c1"># REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY</span>
<span class="c1"># AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,</span>
<span class="c1"># INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM</span>
<span class="c1"># LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE</span>
<span class="c1"># OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR</span>
<span class="c1"># PERFORMANCE OF THIS SOFTWARE.</span>

<span class="c1"># Use gnuplot to graph interesting data from gc_summary lines in rpkid logs.</span>

<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="o">,</span><span class="w"> </span><span class="nn">os</span><span class="o">,</span><span class="w"> </span><span class="nn">time</span>

<span class="k">class</span><span class="w"> </span><span class="nc">datapoint</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

  <span class="n">outtype</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;OUTTYPE&quot;</span><span class="p">,</span> <span class="s2">&quot;png&quot;</span><span class="p">)</span>
  <span class="n">outname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;OUTNAME&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
  <span class="n">timefmt</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;TIMEFMT&quot;</span><span class="p">,</span> <span class="s2">&quot;%T&quot;</span><span class="p">)</span>
  <span class="n">pretend</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;PRETEND_EVERYTHING_CHANGED&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
  <span class="n">threshold</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&quot;THRESHOLD&quot;</span><span class="p">,</span> <span class="s2">&quot;100&quot;</span><span class="p">))</span>

  <span class="n">raw</span> <span class="o">=</span> <span class="p">[]</span>
  <span class="n">filenames</span> <span class="o">=</span> <span class="p">[]</span>

  <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">,</span> <span class="n">process</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">typesig</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">timestamp</span> <span class="o">=</span> <span class="n">timestamp</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">process</span> <span class="o">=</span> <span class="n">process</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">count</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">typesig</span> <span class="o">=</span> <span class="n">typesig</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">line</span> <span class="o">=</span> <span class="n">line</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">typesig</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">filename</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filenames</span><span class="p">:</span>
      <span class="bp">self</span><span class="o">.</span><span class="n">filenames</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>

  <span class="k">def</span><span class="w"> </span><span class="nf">__cmp__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
    <span class="n">c</span> <span class="o">=</span> <span class="n">cmp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">c</span> <span class="k">if</span> <span class="n">c</span> <span class="k">else</span> <span class="n">cmp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">timestamp</span><span class="p">)</span>

  <span class="nd">@classmethod</span>
  <span class="k">def</span><span class="w"> </span><span class="nf">plot</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>

    <span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Looking for interesting records&quot;</span> <span class="o">%</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">)</span>
    <span class="n">changed</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">raw</span><span class="p">:</span>
      <span class="k">if</span> <span class="n">i</span><span class="o">.</span><span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">changed</span><span class="p">:</span>
        <span class="n">changed</span><span class="p">[</span><span class="n">i</span><span class="o">.</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
      <span class="n">changed</span><span class="p">[</span><span class="n">i</span><span class="o">.</span><span class="n">key</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">i</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>
    <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">pretend</span><span class="p">:</span>
      <span class="n">changed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">changed</span><span class="o">.</span><span class="n">iterkeys</span><span class="p">())</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">changed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">k</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">changed</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()</span> <span class="k">if</span> <span class="nb">max</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">-</span> <span class="nb">min</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">&gt;</span> <span class="bp">cls</span><span class="o">.</span><span class="n">threshold</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">changed</span><span class="p">:</span>
      <span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Apparently nothing worth reporting&quot;</span> <span class="o">%</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">)</span>
      <span class="nb">print</span> <span class="s2">&quot;print &#39;Nothing to plot&#39;&quot;</span>
      <span class="k">return</span>

    <span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Header&quot;</span> <span class="o">%</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">)</span>
    <span class="nb">print</span> <span class="s2">&quot;set xdata time&quot;</span>
    <span class="nb">print</span> <span class="s2">&quot;set timefmt &#39;%Y-%m-</span><span class="si">%d</span><span class="s2">T%H:%M:%S&#39;&quot;</span>
    <span class="nb">print</span> <span class="s2">&quot;set format x &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="bp">cls</span><span class="o">.</span><span class="n">timefmt</span>
    <span class="nb">print</span> <span class="s2">&quot;set key right bottom&quot;</span>
    <span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">outname</span><span class="p">:</span>
      <span class="nb">print</span> <span class="s2">&quot;set terminal&quot;</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">outtype</span>
      <span class="nb">print</span> <span class="s2">&quot;set output &#39;</span><span class="si">%s</span><span class="s2">.</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">cls</span><span class="o">.</span><span class="n">outname</span><span class="p">,</span> <span class="bp">cls</span><span class="o">.</span><span class="n">outtype</span><span class="p">)</span>
      <span class="nb">print</span> <span class="s2">&quot;set term png size 1024,1024&quot;</span>
    <span class="nb">print</span> <span class="s2">&quot;plot&quot;</span><span class="p">,</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;&#39;-&#39; using 1:2 with linespoints title &#39;</span><span class="si">%s</span><span class="s2">&#39;&quot;</span> <span class="o">%</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">changed</span><span class="p">)</span>

    <span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Sorting&quot;</span> <span class="o">%</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">)</span>
    <span class="bp">cls</span><span class="o">.</span><span class="n">raw</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>

    <span class="n">key</span> <span class="o">=</span> <span class="kc">None</span>
    <span class="n">proc</span> <span class="o">=</span> <span class="kc">None</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">raw</span><span class="p">:</span>
      <span class="k">if</span> <span class="n">i</span><span class="o">.</span><span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">changed</span><span class="p">:</span>
        <span class="k">continue</span>
      <span class="k">if</span> <span class="n">key</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">i</span><span class="o">.</span><span class="n">key</span> <span class="o">!=</span> <span class="n">key</span><span class="p">:</span>
        <span class="nb">print</span> <span class="s2">&quot;e&quot;</span>
      <span class="k">elif</span> <span class="n">proc</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">i</span><span class="o">.</span><span class="n">process</span> <span class="o">!=</span> <span class="n">proc</span><span class="p">:</span>
        <span class="nb">print</span> <span class="s2">&quot;&quot;</span>
      <span class="n">key</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">key</span>
      <span class="n">proc</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">process</span>
      <span class="nb">print</span> <span class="s2">&quot;#&quot;</span><span class="p">,</span> <span class="n">i</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">i</span><span class="o">.</span><span class="n">line</span>
      <span class="nb">print</span> <span class="n">i</span><span class="o">.</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">i</span><span class="o">.</span><span class="n">count</span>
    <span class="nb">print</span> <span class="s2">&quot;e&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="n">outname</span><span class="p">:</span>
      <span class="nb">print</span> <span class="s2">&quot;pause mouse any&quot;</span>

<span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
  <span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Reading </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">),</span> <span class="n">filename</span><span class="p">)</span>
  <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
    <span class="k">if</span> <span class="s2">&quot;gc_summary:&quot;</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
      <span class="n">word</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span>
      <span class="k">if</span> <span class="n">word</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">isdigit</span><span class="p">()</span> <span class="ow">and</span> <span class="n">word</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;(&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">word</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;)&quot;</span><span class="p">):</span>
        <span class="n">datapoint</span><span class="p">(</span><span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span><span class="p">,</span>
                  <span class="n">timestamp</span> <span class="o">=</span> <span class="n">word</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s2">&quot;T&quot;</span> <span class="o">+</span> <span class="n">word</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
                  <span class="n">process</span>   <span class="o">=</span> <span class="n">word</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
                  <span class="n">count</span>     <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">word</span><span class="p">[</span><span class="mi">4</span><span class="p">]),</span>
                  <span class="n">typesig</span>   <span class="o">=</span> <span class="n">word</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
                  <span class="n">line</span>      <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
 
<span class="nb">print</span> <span class="s2">&quot;# [</span><span class="si">%s</span><span class="s2">] Plotting&quot;</span> <span class="o">%</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%T&quot;</span><span class="p">)</span>
<span class="n">datapoint</span><span class="o">.</span><span class="n">plot</span><span class="p">()</span>
</pre></div>
</code></pre></td></tr></table>
</div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.3</a> (<a href='https://git-scm.com/'>git 2.25.1</a>) at 2025-07-04 13:37:56 +0000</div>
</div> <!-- id=cgit -->
</body>
</html>