<commit_before>{% extends 'layouts/master.html' %}
{% import './macros/paginate.html' as paginate %}
{% import './macros/macros.html' as macros %}

{% block embed %}
  <ol class="breadcrumb">
    <li><a href="/">Home</a></li>
    <li><a href="/me/convos">Private Convos</a></li>
  </ol>

  <!-- Participants list -->
  <div class="well">
    <h4>Participants</h4>
    <p>These are the only people that can see these messages and respond to them.</p>
    <ul>
      {% for user in convo.participants %}
        <li><a href="{{ user.url }}">{{ user.uname }}</a></li>
      {% endfor %}
    </ul>
  </div>

  <!-- Pagination -->
  {{ paginate.render(currPage, totalPages, ctx.request.path) }}

  <div class="page-header" style="border: 0">
    <h2><a href="{{ convo.url }}" style="color: #fff">{{ convo.title }}</a></h2>
  </div>

  <!-- Pms list -->

  <!-- set `post` for now so that I can easily share logic with
       show_topic.html until I decide whether to unify or diverge posts/pms-->
  {% for post in convo.pms %}
    <a name="post-{{ post.id }}"></a>
    <div class="panel panel-default post"
         id="post-{{ post.id }}"
         style="border: 1px solid #111;">
      <div class="panel-heading clearfix"
           style="background-color: #1D1D1D; border-color: #111; border-radius: 0">
        <span class="pull-left">
          <abbr class="timeago" title="{{ post.created_at.toISOString() }}">
            {{ post.formattedCreatedAt }}
          </abbr>
        </span>
        <div class="pull-right post-header">
          <a href="{{ post.url }}/raw">View Raw</a> -
          <a href="{{ post.url }}">
            <span class="glyphicon glyphicon-link"></span>
          </a>
        </div>
      </div> <!-- /.panel-heading -->

      <!-- Panel body -->
      <div class="panel-body" style="background-color: #2E2C2C">

        <!-- Author metadata -->
        <div class="col-sm-2 clearfix text-center post-user-meta">


            <!-- For small devices -->
            <div class="visible-xs-block">
              <div class="media">
                {% if post.user.avatar_url %}
                  <a class="media-left" href="{{ post.user.url }}">
                    <img src="{{ post.user.avatar_url}}" alt="avatar"
                         style="max-width: 60px">
                  </a>
                {% endif %}
                <div class="media-body">
                  <h4 class="media-heading">
                    <a href="{{ post.user.url }}">
                      {{ post.user.uname }}
                    </a>
                    {% if post.user.custom_title %}
                      <small><span class="text-muted">{{ post.user.custom_title }}</span></small>
                    {% endif %}
                  </h4>
                  <div class="pull-left">
                    {{ post.user.role|capitalize }}<br>
                    {{ macros.onlineStatus(post.user) }}
                  </div>
                </div>
              </div>
            </div> <!-- /small devices -->

            <!-- For larger-than-smartphone devices -->
            <div class="hidden-xs">
              <div class="user-uname">
                <a href="{{ post.user.url }}">
                  {{ post.user.uname }}
                </a>
              </div>

              {% if post.user.avatar_url %}
                <div class="post-avatar"
                     style="margin-top: 10px;">
                  <img src="{{ post.user.avatar_url}}">
                </div>
              {% endif %}

              <div class="user-role" style="margin-top: 10px;">
                {{ post.user.role|capitalize }}
              </div>

              <!-- Online status -->

              {{ macros.onlineStatus(post.user) }}

            </div> <!-- /.hidden-xs -->

        </div> <!-- /.col-sm-2 post-meta -->

        <!-- Post text -->
        <div class="col-sm-10">
          <!-- Post text -->
          {{- macros.renderPost(post) -}}
          <!-- Signature -->
          {{- macros.renderSig(post.user) -}}
        </div>

      </div> <!-- /.panel-body -->

      <!-- Panel footer -->
      <div class="panel-footer clearfix"
           style="background-color: #2E2C2C; border-radius: 0; border: 0">
        <!-- IP address -->
        {% if ctx.can(ctx.currUser, 'READ_USER_IP', post.user) %}
          <div class="pull-left"
               style="margin-left: 5px; color: #6E6B6B">
            {{ post.ip_address }}
          </div>
        {% endif %}
        <!-- Reply button -->
        <a href=""
           class="btn btn-default btn-xs pull-right post-reply-btn"
           post-id="{{ post.id }}"
           post-uname="{{ post.user.uname }}"
           style="margin-left: 5px"
           {% if !ctx.can(ctx.currUser, 'CREATE_PM', convo) %}disabled{% endif %}
           >Quote</a>
        <!-- Edit button -->
        {% if ctx.can(ctx.currUser, 'UPDATE_PM', post) %}
          <a href="{{ post.url }}/edit"
             class="btn btn-default btn-xs pull-right post-edit-btn"
             style="margin-left: 5px;"
             post-id={{ post.id }}
            >Edit</a>
        {% endif %}
      </div> <!-- /.panel-footer -->
    </div> <!-- /.panel -->
  {% endfor %}

  <!-- Top -->
  <div style="display: block; margin-bottom: 20px;">
    <a href="#" class="top-link">&uarr; Top</a>
  </div>

  <!-- Pagination -->
  {{ paginate.render(currPage, totalPages, ctx.request.path) }}

  <!-- New post forum -->

  <h2>New Reply</h2>

  <ul>
    <li>Before submitting your post, it's wise to copy it somewhere so that you don't lose it in the event of server error.</li>
    <li>Check out the BBCode Cheatsheet below the editor. It's pretty basic for now, but I will add more BBCode over time. Check the cheatsheet every once in a while for updates.</li>
    <li>Post limit: {{ ctx.config.MAX_POST_LENGTH|commafy }} chars</li>
  </ul>
  <form id="reply-form" role="form" method="post" action="{{ convo.url }}/pms">
    <div class="form-group">
      <textarea rows=10
                id="reply-input"
                name="markup"
                class="form-control"
                placeholder="Click here and begin writing"></textarea>
    </div>
    <input type="submit" class="btn btn-primary" value="Post Reply"></input>
  </form>

  {% include 'partials/bbcode_cheatsheet.html' %}

{% endblock %}

{% block scripts %}
  <script>
      $('input[type="submit"]').on('click', function(e) {
        var $this = $(this);
        if ($this.data('already-clicked'))
          return false;
        $this.data('already-clicked', true);
      });
  </script>
  <script>
    // Render posts only as they appear in the user's browser
    $('.post-body, .post-sig-markdown').appear();
    $('.post-body, .post-sig-markdown').on('appear', function(e) {
      if (!$(this).attr('data-rendered')) {
        var $this = $(this);
        $this.html(markdown.toHTML($this.text()));
        $this.attr('data-rendered', true);
      }
    });
  </script>
  <script>
    $(function() {
      $('#reply-input').bbcode({
        charLimit: {{ ctx.config.MAX_POST_LENGTH }}
      });
    });
  </script>

  {#
          REPLY BUTTON
  #}
  <script>
$(function() {
  $('.post-reply-btn').click(function(e) {
    e.preventDefault();
    $reply_btn = $(this);
    $reply_btn.addClass('disabled').html('Loading...');
    var post_id = $reply_btn.attr('post-id');
    var uname = $reply_btn.attr('post-uname');
    var post_url = '/pms/' + post_id + '/raw';
    $.get(post_url, function(markup) {
      console.log('returned')
      $reply_btn.removeClass('disabled').html('Reply');

      var quote_markup = '[quote=@' + uname + ']\n' +
        extractTopLevelMarkup(markup.trim())  +
        '\n[/quote]\n';

      var $reply_textarea = $('#reply-form textarea');
      var prev_content = $('textarea').val().trim();
      // Only add \n\n padding if there was already content in textarea
      var padding = (function() {
        if (prev_content.length === 0) {
          return '';
        }
        return '\n\n'
      })();
      $reply_textarea.focus().val('').val(prev_content + padding + quote_markup + '\n');
      $reply_textarea.scrollTop($reply_textarea[0].scrollHeight);

      $('html, body').animate({
        scrollTop: $reply_textarea.offset().top
      }, 100);

    });
  });
});
  </script>

  {#
          EDIT POST BUTTON
  #}
  <script>
$(function() {
  $('.post-edit-btn').click(function(e) {
    e.preventDefault();
    $post_edit_btn = $(this);
    $post_edit_btn.addClass('disabled');
    var post_id = $(this).attr('post-id');
    var $post_body = $('#post-' + post_id + ' .post-content');
    var prev_body = $post_body.html();
    var $spinner = $('<span><img src="/img/spinner.gif"> Loading edit form...</span>');
    $post_body.html($spinner);
    $cancel_btn = $('<button style="margin-left: 5px;" class="btn btn-default post-edit-cancel-btn">Cancel</button>');

    $.ajax({
      url: '/pms/' + post_id + '/raw',
      dataType: 'html',
      cache: false,
      success: function(post_text) {
        console.log(post_text);
        var $post_editor = $('<textarea class="post-editor form-control"></textarea>');
        $spinner.remove();

        // Warn about Markdown->BBCode conversion on Markdown posts.
        // A post is a Markdown post if its post-body is wrapped with
        // .post-body instead of .post-body-html
        if ($('#post-' + post_id + ' .post-body')[0]) {
          $post_body.append(
            '<p style="color: salmon">'+
            'This PM uses the old formatting system (Markdown) before we had BBCode. If you click "Save", then the forum will assume that you\'ve converted this PM to BBCode. If you don\'t want that to happen, then click "Cancel".'+
            '</p><p style="color: salmon">'+
            'For example, <code>[Click Me](http://example.com)</code> (Old system) is now <code>[url=http://example.com]Click Me[/url]</code> (BBCode)'+
            '</p>'
          );
        }
        $post_body.append($post_editor);
        $post_editor.bbcode({
          charLimit: {{ ctx.config.MAX_POST_LENGTH }},
          savable: true,
          onSave: function(e) {
            //
            $success_btn = $post_body.find('.btn-success');
            $success_btn.html('Saving...');
            $success_btn.attr('disabled', true);
            $post_body.find('.btn').attr('disabled', true);

            var text_to_save = e.getContent();
            $.ajax({
              url: '/api/pms/' + post_id,
              dataType: 'json',
              type: 'POST',
              headers: { 'X-HTTP-Method-Override': 'PUT' },
              data: { markup: text_to_save },
              success: function(updated_post) {
                $post_body.html(updated_post.html);
                $post_edit_btn.removeClass('disabled');
                // Set the post's .edited-marker to ' edited'
                var $edited_marker = $('#post-' + post_id + ' .edited-marker')
                $edited_marker.html(' edited');
              }
            })
          }
        });

        // Gotta set the text before the .markdown() call or else
        // .markdown() escapes html entities.
        $post_body.find('textarea').val(post_text)

        // Scroll to editor over 500ms so user can re-orient themselves
        $('body').animate({
            scrollTop: $post_body.offset().top
        }, 500);

        $cancel_btn.insertAfter(
          $('#post-' + post_id + ' .md-footer button[data-handler="cmdSave"]')
        );

        $($cancel_btn).click(function() {
          $post_body.html(prev_body);
          $post_edit_btn.removeClass('disabled');
        });
      }
    });

    return false;
  });
});
  </script>
{% endblock%}
<commit_msg>Implement ip-lookup from PMs<commit_after>{% extends 'layouts/master.html' %}
{% import './macros/paginate.html' as paginate %}
{% import './macros/macros.html' as macros %}

{% block embed %}
  <ol class="breadcrumb">
    <li><a href="/">Home</a></li>
    <li><a href="/me/convos">Private Convos</a></li>
  </ol>

  <!-- Participants list -->
  <div class="well">
    <h4>Participants</h4>
    <p>These are the only people that can see these messages and respond to them.</p>
    <ul>
      {% for user in convo.participants %}
        <li><a href="{{ user.url }}">{{ user.uname }}</a></li>
      {% endfor %}
    </ul>
  </div>

  <!-- Pagination -->
  {{ paginate.render(currPage, totalPages, ctx.request.path) }}

  <div class="page-header" style="border: 0">
    <h2><a href="{{ convo.url }}" style="color: #fff">{{ convo.title }}</a></h2>
  </div>

  <!-- Pms list -->

  <!-- set `post` for now so that I can easily share logic with
       show_topic.html until I decide whether to unify or diverge posts/pms-->
  {% for post in convo.pms %}
    <a name="post-{{ post.id }}"></a>
    <div class="panel panel-default post"
         id="post-{{ post.id }}"
         style="border: 1px solid #111;">
      <div class="panel-heading clearfix"
           style="background-color: #1D1D1D; border-color: #111; border-radius: 0">
        <span class="pull-left">
          <abbr class="timeago" title="{{ post.created_at.toISOString() }}">
            {{ post.formattedCreatedAt }}
          </abbr>
        </span>
        <div class="pull-right post-header">
          <a href="{{ post.url }}/raw">View Raw</a> -
          <a href="{{ post.url }}">
            <span class="glyphicon glyphicon-link"></span>
          </a>
        </div>
      </div> <!-- /.panel-heading -->

      <!-- Panel body -->
      <div class="panel-body" style="background-color: #2E2C2C">

        <!-- Author metadata -->
        <div class="col-sm-2 clearfix text-center post-user-meta">


            <!-- For small devices -->
            <div class="visible-xs-block">
              <div class="media">
                {% if post.user.avatar_url %}
                  <a class="media-left" href="{{ post.user.url }}">
                    <img src="{{ post.user.avatar_url}}" alt="avatar"
                         style="max-width: 60px">
                  </a>
                {% endif %}
                <div class="media-body">
                  <h4 class="media-heading">
                    <a href="{{ post.user.url }}">
                      {{ post.user.uname }}
                    </a>
                    {% if post.user.custom_title %}
                      <small><span class="text-muted">{{ post.user.custom_title }}</span></small>
                    {% endif %}
                  </h4>
                  <div class="pull-left">
                    {{ post.user.role|capitalize }}<br>
                    {{ macros.onlineStatus(post.user) }}
                  </div>
                </div>
              </div>
            </div> <!-- /small devices -->

            <!-- For larger-than-smartphone devices -->
            <div class="hidden-xs">
              <div class="user-uname">
                <a href="{{ post.user.url }}">
                  {{ post.user.uname }}
                </a>
              </div>

              {% if post.user.avatar_url %}
                <div class="post-avatar"
                     style="margin-top: 10px;">
                  <img src="{{ post.user.avatar_url}}">
                </div>
              {% endif %}

              <div class="user-role" style="margin-top: 10px;">
                {{ post.user.role|capitalize }}
              </div>

              <!-- Online status -->

              {{ macros.onlineStatus(post.user) }}

            </div> <!-- /.hidden-xs -->

        </div> <!-- /.col-sm-2 post-meta -->

        <!-- Post text -->
        <div class="col-sm-10">
          <!-- Post text -->
          {{- macros.renderPost(post) -}}
          <!-- Signature -->
          {{- macros.renderSig(post.user) -}}
        </div>

      </div> <!-- /.panel-body -->

      <!-- Panel footer -->
      <div class="panel-footer clearfix"
           style="background-color: #2E2C2C; border-radius: 0; border: 0">
        <!-- IP address -->
        {% if ctx.can(ctx.currUser, 'READ_USER_IP', post.user) %}
          <div class="pull-left" style="margin-left: 5px; color: #6E6B6B">
            <a href="/ips/{{ post.ip_address }}" class="text-muted">
              {{ post.ip_address }}
            </a>
          </div>
        {% endif %}
        <!-- Reply button -->
        <a href=""
           class="btn btn-default btn-xs pull-right post-reply-btn"
           post-id="{{ post.id }}"
           post-uname="{{ post.user.uname }}"
           style="margin-left: 5px"
           {% if !ctx.can(ctx.currUser, 'CREATE_PM', convo) %}disabled{% endif %}
           >Quote</a>
        <!-- Edit button -->
        {% if ctx.can(ctx.currUser, 'UPDATE_PM', post) %}
          <a href="{{ post.url }}/edit"
             class="btn btn-default btn-xs pull-right post-edit-btn"
             style="margin-left: 5px;"
             post-id={{ post.id }}
            >Edit</a>
        {% endif %}
      </div> <!-- /.panel-footer -->
    </div> <!-- /.panel -->
  {% endfor %}

  <!-- Top -->
  <div style="display: block; margin-bottom: 20px;">
    <a href="#" class="top-link">&uarr; Top</a>
  </div>

  <!-- Pagination -->
  {{ paginate.render(currPage, totalPages, ctx.request.path) }}

  <!-- New post forum -->

  <h2>New Reply</h2>

  <ul>
    <li>Before submitting your post, it's wise to copy it somewhere so that you don't lose it in the event of server error.</li>
    <li>Check out the BBCode Cheatsheet below the editor. It's pretty basic for now, but I will add more BBCode over time. Check the cheatsheet every once in a while for updates.</li>
    <li>Post limit: {{ ctx.config.MAX_POST_LENGTH|commafy }} chars</li>
  </ul>
  <form id="reply-form" role="form" method="post" action="{{ convo.url }}/pms">
    <div class="form-group">
      <textarea rows=10
                id="reply-input"
                name="markup"
                class="form-control"
                placeholder="Click here and begin writing"></textarea>
    </div>
    <input type="submit" class="btn btn-primary" value="Post Reply"></input>
  </form>

  {% include 'partials/bbcode_cheatsheet.html' %}

{% endblock %}

{% block scripts %}
  <script>
      $('input[type="submit"]').on('click', function(e) {
        var $this = $(this);
        if ($this.data('already-clicked'))
          return false;
        $this.data('already-clicked', true);
      });
  </script>
  <script>
    // Render posts only as they appear in the user's browser
    $('.post-body, .post-sig-markdown').appear();
    $('.post-body, .post-sig-markdown').on('appear', function(e) {
      if (!$(this).attr('data-rendered')) {
        var $this = $(this);
        $this.html(markdown.toHTML($this.text()));
        $this.attr('data-rendered', true);
      }
    });
  </script>
  <script>
    $(function() {
      $('#reply-input').bbcode({
        charLimit: {{ ctx.config.MAX_POST_LENGTH }}
      });
    });
  </script>

  {#
          REPLY BUTTON
  #}
  <script>
$(function() {
  $('.post-reply-btn').click(function(e) {
    e.preventDefault();
    $reply_btn = $(this);
    $reply_btn.addClass('disabled').html('Loading...');
    var post_id = $reply_btn.attr('post-id');
    var uname = $reply_btn.attr('post-uname');
    var post_url = '/pms/' + post_id + '/raw';
    $.get(post_url, function(markup) {
      console.log('returned')
      $reply_btn.removeClass('disabled').html('Reply');

      var quote_markup = '[quote=@' + uname + ']\n' +
        extractTopLevelMarkup(markup.trim())  +
        '\n[/quote]\n';

      var $reply_textarea = $('#reply-form textarea');
      var prev_content = $('textarea').val().trim();
      // Only add \n\n padding if there was already content in textarea
      var padding = (function() {
        if (prev_content.length === 0) {
          return '';
        }
        return '\n\n'
      })();
      $reply_textarea.focus().val('').val(prev_content + padding + quote_markup + '\n');
      $reply_textarea.scrollTop($reply_textarea[0].scrollHeight);

      $('html, body').animate({
        scrollTop: $reply_textarea.offset().top
      }, 100);

    });
  });
});
  </script>

  {#
          EDIT POST BUTTON
  #}
  <script>
$(function() {
  $('.post-edit-btn').click(function(e) {
    e.preventDefault();
    $post_edit_btn = $(this);
    $post_edit_btn.addClass('disabled');
    var post_id = $(this).attr('post-id');
    var $post_body = $('#post-' + post_id + ' .post-content');
    var prev_body = $post_body.html();
    var $spinner = $('<span><img src="/img/spinner.gif"> Loading edit form...</span>');
    $post_body.html($spinner);
    $cancel_btn = $('<button style="margin-left: 5px;" class="btn btn-default post-edit-cancel-btn">Cancel</button>');

    $.ajax({
      url: '/pms/' + post_id + '/raw',
      dataType: 'html',
      cache: false,
      success: function(post_text) {
        console.log(post_text);
        var $post_editor = $('<textarea class="post-editor form-control"></textarea>');
        $spinner.remove();

        // Warn about Markdown->BBCode conversion on Markdown posts.
        // A post is a Markdown post if its post-body is wrapped with
        // .post-body instead of .post-body-html
        if ($('#post-' + post_id + ' .post-body')[0]) {
          $post_body.append(
            '<p style="color: salmon">'+
            'This PM uses the old formatting system (Markdown) before we had BBCode. If you click "Save", then the forum will assume that you\'ve converted this PM to BBCode. If you don\'t want that to happen, then click "Cancel".'+
            '</p><p style="color: salmon">'+
            'For example, <code>[Click Me](http://example.com)</code> (Old system) is now <code>[url=http://example.com]Click Me[/url]</code> (BBCode)'+
            '</p>'
          );
        }
        $post_body.append($post_editor);
        $post_editor.bbcode({
          charLimit: {{ ctx.config.MAX_POST_LENGTH }},
          savable: true,
          onSave: function(e) {
            //
            $success_btn = $post_body.find('.btn-success');
            $success_btn.html('Saving...');
            $success_btn.attr('disabled', true);
            $post_body.find('.btn').attr('disabled', true);

            var text_to_save = e.getContent();
            $.ajax({
              url: '/api/pms/' + post_id,
              dataType: 'json',
              type: 'POST',
              headers: { 'X-HTTP-Method-Override': 'PUT' },
              data: { markup: text_to_save },
              success: function(updated_post) {
                $post_body.html(updated_post.html);
                $post_edit_btn.removeClass('disabled');
                // Set the post's .edited-marker to ' edited'
                var $edited_marker = $('#post-' + post_id + ' .edited-marker')
                $edited_marker.html(' edited');
              }
            })
          }
        });

        // Gotta set the text before the .markdown() call or else
        // .markdown() escapes html entities.
        $post_body.find('textarea').val(post_text)

        // Scroll to editor over 500ms so user can re-orient themselves
        $('body').animate({
            scrollTop: $post_body.offset().top
        }, 500);

        $cancel_btn.insertAfter(
          $('#post-' + post_id + ' .md-footer button[data-handler="cmdSave"]')
        );

        $($cancel_btn).click(function() {
          $post_body.html(prev_body);
          $post_edit_btn.removeClass('disabled');
        });
      }
    });

    return false;
  });
});
  </script>
{% endblock%}

{'fraction_non_alphanumeric': 0.18472092826289488, 'fraction_numerical': 0.0051664266960277806, 'mean_word_length': 1.8641600970285022, 'pattern_counts': {'":': 0, '<': 333, '<?xml version=': 0, '>': 335, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2320457', 'n_tokens_mistral': 7571, 'n_tokens_neox': 7125, 'n_words': 1580}