config

# -*- mode:cperl -*-
do '/home/alex/password.pl';
$ScriptName = 'https://alexschroeder.ch/software';
$SiteName = 'Software';
$CookieName = 'Software';
$HomePage = 'Software';
$RCName = 'Recent Changes';
$UploadAllowed = 1;
$StyleSheet = '/css/software.css';
$TagUrl = "$ScriptName/%s";
$MatchingPages = 1;
$CommentsPrefix = 'Comments_on_';
$KeepDays = 14;

# In this config file we use an extra backslash when writing tag\:Open
# and the like such that we can post this file to the wiki and not
# have it actually count as tagged.

$Action{'new-issue'} = \&new_issue;

sub new_issue {
  my $tag = GetParam('tag');
  print GetHeader('', T('New Issue')), $q->start_div({-class=>'content issue'});
  my $html = GetFormStart(undef, 'post', 'issue') . $q->start_p;
  $html .= T('The issue title is required:');
  $html .= $q->end_p, $q->start_p;
  $html .= '<input type="text" name="title" class="fullwidth" required />';
  $html .= $q->end_p, $q->start_p;
  $html .= T('Please provide additional details without overwriting the tags:');
  $html .= $q->end_p, $q->start_p;
  $html .= GetTextArea('text', "\n\n\nTags: " . join(" ", map { "[[tag:$_]]" } 'Issue', 'Open', $tag) . "\n");
  $html .= $q->end_p, $q->start_p;
  my $username = GetParam('username', '');
  $html .= $q->p($q->label({-for=>'username'}, T('Username:')).' '
		 .$q->textfield(-name=>'username', -id=>'username', -default=>$username,
				-override=>1, -size=>20, -maxlength=>50))
      .$q->p($q->submit(-name=>'Save', -accesskey=>T('s'), -value=>T('Save')),
	     ($upload ? '' : ' ' . $q->submit(-name=>'Preview', -accesskey=>T('p'), -value=>T('Preview'))).
	     ' '.$q->submit(-name=>'Cancel', -value=>T('Cancel')));
  $html .= $q->end_p, $q->end_form;
  foreach my $sub (@MyFormChanges) {
    $html = $sub->($html, 'issue');
  }
  print $html, $q->end_div;
  PrintFooter($id, 'edit');
}

$Action{'search-issue'} = \&search_issue;

sub search_issue {
  my $tag = GetParam('tag');
  ReportError("Tag Missing") unless $tag;
  DoSearch(join(" ", map { "tag:$_" } 'issue', $tag));
}

$Action{'changed-issues'} = \&changed_issues;

sub changed_issues {
  my $tag = GetParam('tag');
  ReportError("Tag Missing") unless $tag;
  SetParam("rcfilteronly", join(" ", map { "tag:$_" } 'issue', $tag));
  BrowseRc();
}

$Action{'close-issue'} = \&close_issue;

sub close_issue {
  my $id = shift;
  my $text = GetPageContent($id) if ValidIdOrDie($id);
  $text =~ s/\[\[tag\:Open\]\]/[[tag\:Closed]]/ # backslash required, see note
    or ReportError("This page is not tagged as Open");
  SetParam('text', $text);
  DoPost($id);
}

$Action{'reopen-issue'} = \&reopen_issue;

sub reopen_issue {
  my $id = shift;
  my $text = GetPageContent($id) if ValidIdOrDie($id);
  $text =~ s/\[\[tag\:Closed\]\]/[[tag\:Open]]/ # backslash required, see note
    or ReportError("This page is not tagged as Closed");
  SetParam('text', $text);
  DoPost($id);
}

push(@MyRules, \&small_extras);

sub small_extras {
  if ($bol and m/\G----+\s*\n/gc) {
    return CloseHtmlEnvironments()
      . $q->hr()
      . AddHtmlEnvironment('p');
  }
  return;
}

$RuleOrder{\&TagsRule} = 10; # make sure we can change this

push(@MyRules, \&issue_tags);

sub issue_tags {
  if (m/\G\[\[tag\:Open\]\]/gc) { # backslash required, see note
    return GetPageLink("Open")
      . CloseHtmlEnvironments()
      . AddHtmlEnvironment('p')
      . ScriptLink('action=close-issue;id=' . UrlEncode(FreeToNormal(GetId())),
		   'Close issue',
		   'button');
  } elsif (m/\G\[\[tag\:Closed\]\]/gc) { # backslash required, see note
    return GetPageLink("Closed")
      . CloseHtmlEnvironments()
      . AddHtmlEnvironment('p')
      . ScriptLink('action=reopen-issue;id=' . UrlEncode(FreeToNormal(GetId())),
		   'Reopen issue',
		   'button');
  }
  return;
}

push(@MyRules, \&source_template);

sub source_template {
  if (m/\G(&lt;source\/*&gt;)/gc) {
    Clean(CloseHtmlEnvironments()); # if block level dirty block
    Dirty($1);
    my ($oldpos, $old_) = ((pos), $_);
    my $id = FreeToNormal(GetId());
    my $text = NormalToFree($id);
    my $esc = UrlEncode($text);
    my $tag = lc($id);
    my $file = $tag;
    $file =~ tr/_/-/;
    my %hash = ();
    foreach my $id (SearchTitleAndBody(join(" ", map { "tag:$_" } 'issue', 'open', $tag))) {
      $hash{$id} = 1;
    }
    my @found = map { $q->li(GetPageLink($_)) } sort keys %hash;
    push(@found, "none") unless @found;
    # This is a dirty rule: the HTML output changes even if this page
    # is not edited. It depends on other pages. Thus, it must not be
    # cached. It's "dirty".
    print <<"EOT";
<h2>Source Code</h2>
<p>How to get a copy of the source code from git:</p>
<pre>git clone https://alexschroeder.ch/cgit/$file</pre>
<p>You can also <a href="https://alexschroeder.ch/cgit/$file/about">browse the code on the web</a>.</p>
<h2>Issues</h2>
<p>
<a class="button" href="https://alexschroeder.ch/software?action=search-issue;tag=$tag">Search issue</a>
<a class="button" href="https://alexschroeder.ch/software?action=new-issue;tag=$esc">New issue</a>
<a class="button" href="https://alexschroeder.ch/software?action=changed-issues;tag=$tag">Changes</a>
</p>
<h2>Open</h2>
<div class="search list">
<ul>@found</ul>
</div>
EOT
    Clean(AddHtmlEnvironment('p'));
    ($_, pos) = ($old_, $oldpos); # restore \G (assignment order matters!)
    return '';
  }
  return;
}