diff options
| -rw-r--r-- | _data/scripts.yaml | 7 | ||||
| -rw-r--r-- | assets/js/votes.js | 200 | ||||
| -rw-r--r-- | index.html | 2 | ||||
| -rw-r--r-- | scripts/reorder.pl | 311 | 
4 files changed, 305 insertions, 215 deletions
| diff --git a/_data/scripts.yaml b/_data/scripts.yaml index 25cb85e..e2ed384 100644 --- a/_data/scripts.yaml +++ b/_data/scripts.yaml @@ -3771,13 +3771,14 @@    url: http://irssi.dgl.cx/    version: '1'  - -  authors: 'Isaac G' -  contact: irssi@isaac.otherinbox.com +  authors: 'Isaac Good' +  contact: irssi@isaacgood.com    description: 'Reordering windows based on a textfile.'    filename: reorder.pl    license: GPL -  modified: '2010-02-12 22:42:13' +  modified: '2016-12-06 18:47:28'    name: reorder +  version: '1.0'  -    authors: BC-bd    contact: bd@bc-bd.org diff --git a/assets/js/votes.js b/assets/js/votes.js index 4fb585d..2fa9097 100644 --- a/assets/js/votes.js +++ b/assets/js/votes.js @@ -1,75 +1,153 @@  (function(document, $){      'use strict';      var jsonpRe = /^\/\*[\s\S]*?\*\/jsonp\(([\s\S]*)\)$/m; +    var ghLimits = {search: {}, core: {}}; +    var stopId = 0; +    var queue = {search: [], core: []}; +    var todo = 1; -    function requestAll(start) { -	$.ajax({ +    function requestLater(what, how, arg) { +	var when = rateTimeout(what); +	if (when >= 0) { +	    var empty = queue[what].length == 0; +	    queue[what].push([how, arg]); +	    if (empty) window.setTimeout(function(){reQueue(what);}, when); +	} else { +	    ghLimits[what].remaining--; +	    how(arg); +	} +    } + +    function reQueue(what) { +	limitsThen(what, function(q) { +	    q.forEach(function(e) { +		requestLater(what, e[0], e[1]); +	    }); +	}, queue[what].splice(0, queue[what].length)); +    } + +    function signalDone() { +	if (!todo) $("#th-votes").html("Votes"); +    } + +    function _jsonpToJson(dta, typ) { +	if (typ == "json") { +	    return dta.replace(jsonpRe, "$1"); +	} +	return dta; +    } + +    function jj(url) { +	return $.ajax({  	    accepts: { json: 'application/vnd.github.squirrel-girl-preview' },  	    dataType: 'json', -	    url: start, +	    url: url + (url.indexOf('callback=') === -1 +			? (url.indexOf('?') === -1 ? '?' : ';') + 'callback=jsonp' +			: ''),  	    jsonp: false,  	    jsonpCallback: 'jsonp', -	    dataFilter: function(dta, typ) { -		if (typ == "json") { -		    return dta.replace(jsonpRe, "$1"); -		} -		return dta; -	    } -	}) -	    .done(function(r) { -		var remaining = r.meta['X-RateLimit-Remaining']; -		var rateReset = r.meta['X-RateLimit-Reset']; -		var timeOut = 0; -		var hasMore = false; -		if (remaining < 10) { -		    timeOut = 1000 + rateReset * 1000 - (new Date() / 1); -		} -		if (timeOut < 0) timeOut = 0; -		if (r.meta.Link) { -		    r.meta.Link.forEach(function(l) { -			if (l[1].rel == "next") { -			    window.setTimeout(function(){requestAll(l[0]);}, timeOut); -			    hasMore = true; -			    return; -			} -		    }); -		} -		if (timeOut > 0) { -		    timeOut += 1000; +	    dataFilter: _jsonpToJson +	}); +    } + +    function searchVotes(url) { +	var start = url.indexOf("//") !== -1 ? url +		: 'https://api.github.com/search/issues?q=votes+in:title+state:closed+type:issue+' +		+ 'repo:' + url + ';sort=updated'; +	jj(start).done(function(r) { +	    var hasMore = fetchNext('search', r.meta, searchVotes); +	    if (hasMore) todo++; +	    r.data.items.forEach(function(e) { +		if (stopId && e.number > stopId) return; +		if (e.title != "votes") return; +		if (e.locked) { stopId = e.number; return; } +		todo++; +		requestLater('core', requestComments, e.comments_url); +		todo++; +		requestLater('core', requestComments, e.comments_url + '?page=2'); +		todo++; +		requestLater('core', requestComments, e.comments_url + '?page=3'); +		//todo++; +		//requestLater('core', requestComments, e.comments_url + '?page=4'); +	    }); +	    todo--; +	    signalDone(); +	}); +    } + +    function rateTimeout(what) { +	if ($.isEmptyObject(ghLimits[what])) return -1; + +	var remaining = ghLimits[what].remaining; +	var rateReset = ghLimits[what].reset; +	var limit = ghLimits[what].limit; + +	var timeOut = -1; +	if (remaining < Math.log(limit) + Math.sqrt(limit)) { +	    timeOut = 1000 + rateReset * 1000 - (new Date() / 1); +	    if (timeOut < -1) timeOut = 0; +	} +	return timeOut; +    } + +    function updateLimits(what, meta) { +	ghLimits[what].remaining = meta['X-RateLimit-Remaining']; +	ghLimits[what].reset = meta['X-RateLimit-Reset']; +    } + +    function fetchNext(what, meta, how) { +	var hasMore = false; +	updateLimits(what, meta); +	if (meta.Link) { +	    meta.Link.forEach(function(l) { +		if (l[1].rel == "next") { +		    hasMore = true; +		    requestLater(what, how, l[0]); +		    return;  		} +	    }); +	} +	return hasMore; +    } -		r.data.forEach(function(e) { -		    e.body = e.body.replace(/\r/g, ""); -		    var redir = e.body.match(/^#(\d+)$/); -		    if (redir) { -			var l = start.replace(/(\/issues\/)\d+(\/comments\?)/, "$1" + redir[1] + "$2").replace(/&.*/, ""); -			window.setTimeout(function(){requestAll(l);}, timeOut); -			hasMore = true; -			return; -		    } -			 -		    var lines = e.body.split("\n"); -		    var script = lines[0].replace(/[^-a-zA-Z0-9_]/g, "_"); -		    if (script == "comment") { -			script = "adv_windowlist_pl"; -		    } -		    var st = "#script-" + script + " .votes"; -		    var row = $(st); -		    if (row.length) { -			var votes = 1+ e.reactions['+1'] - e.reactions['-1']; -			var link = "*"; -			if (e.reactions['heart'] >= votes) { -			    link = "💜"; -			} -			row.html( "" + votes ); -			 -			row.append("<span><a data-toggle=\"tooltip\" title=\"vote on github\" href=\"" + e.html_url + "\">"+link+"</a></span>"); -		    } -		}); -		if (!hasMore) { -		    $("#th-votes").html("Votes"); +    function requestComments(start) { +	jj(start).done(function(r) { +	    updateLimits('core', r.meta); +	    if (r.meta.status == 403 && !r.meta['X-RateLimit-RateLimit']) { +		requestLater('core', requestComments, start); +		return; +	    } +	    //var hasMore = fetchNext('core', r.meta, requestComments); +	    //if (hasMore) todo++; +	    r.data.some(function(e) { +		e.body = e.body.replace(/\r/g, ""); +		var lines = e.body.split("\n"); +		var redir = e.body.match(/^#(\d+)$/); +		if (redir) return true; +		var script = lines[0].replace(/^## /, "").replace(/[^-a-zA-Z0-9_]/g, "_"); +		var row = $("#script-" + script + " .votes"); +		if (row.length) { +		    var votes = 1+ e.reactions['+1'] - e.reactions['-1']; +		    var link = "*"; +		    if (e.reactions['heart'] >= votes) link = "💜"; +		    row.html( "" + votes ); +		    row.append("<span><a data-toggle=\"tooltip\" title=\"vote on github\" href=\"" +			       + e.html_url + "\">"+link+"</a></span>");  		} +		return false;  	    }); +	    todo--; +	    signalDone(); +	});      } -    requestAll('https://api.github.com/repos/ailin-nemui/scripts.irssi.org/issues/2/comments?callback=jsonp'); + +    function limitsThen(what, how, arg) { +	jj('https://api.github.com/rate_limit').done(function(r) { +	    ghLimits = r.data.resources; +	    requestLater(what, how, arg); +	}); +    } + +    limitsThen('search', searchVotes, 'ailin-nemui/scripts.irssi.org'); +  })(document, $); @@ -50,7 +50,7 @@ layout: default                      <th class="sorttable_alpha">Description</th>                      <th class="sorttable_alpha">Authors</th>                      <th class="sorttable_alpha">Modified</th> -                    <th class="sorttable_numeric" id="th-votes">…</th> +                    <th class="sorttable_numeric" id="th-votes">……</th>                  </tr>              </thead>              <tbody> diff --git a/scripts/reorder.pl b/scripts/reorder.pl index 7bec6b8..ce82fa4 100644 --- a/scripts/reorder.pl +++ b/scripts/reorder.pl @@ -1,150 +1,161 @@ -# Save window layout to an arbitrary file and load layouts upon demand
 -# Useful for being able to temporarily reorder your windows and then reverting to your "normal" layout
 -# Also useful as an easy way to reorder your windows
 -#
 -# A special thanks to billnye, Zed` and Bazerka for their help
 -#
 -# Usage:
 -#  /layout_save filename
 -#    Saves the layout to the textfile "filename.layout"
 -#  /layout_load filename
 -#    Loads the layout from the textfile "filename.layout"
 -#  /set layout_savepath path
 -#    Use to set a default path for layouts
 -#
 -# TODO:
 -#   Check the layout file for a number used twice
 -#
 -
 -use strict;
 -use Irssi;
 -use Data::Dumper;
 -use vars qw($VERSION %IRSSI);
 -
 -%IRSSI = (
 -	authors     => "Isaac G",
 -	contact     => "irssi\@isaac.otherinbox.com",
 -	name        => "reorder",
 -	description => "Reordering windows based on a textfile.",
 -	license     => "GPL",
 -);
 -
 -sub doFilenameFixing
 -{
 -	my ($filename) = @_;
 -	unless ($filename)
 -	{
 -		print "No filename specified!";
 -		return;
 -	}
 -
 -	$filename = glob($filename);
 -
 -	if ($filename =~ /\//)
 -	{
 -		unless ($filename =~ /^\//)
 -		{
 -			print "I don't like /'s in filenames. Unless you want to specify an absolute path.";
 -			return;
 -		}
 -		# Let it go?
 -	}
 -
 -	$filename .= '.layout' unless ($filename =~ /.layout$/);
 -
 -	my $path = Irssi::settings_get_str('layout_savepath');
 -	$path .= '/' unless ($path =~ /\/$/);
 -	$filename = $path . $filename unless ($filename =~ /\//);
 -
 -	return $filename;
 -}
 -
 -sub canReadFile
 -{
 -	my ($filename) = @_;
 -	unless (-f $filename)
 -	{
 -		print "No such file $filename";
 -		return;
 -	}
 -	unless (-r $filename)
 -	{
 -		print "Can not read file $filename";
 -		return;
 -	}
 -	return 1;
 -}
 -
 -# Save a list of refnum and window info to file
 -sub cmd_layout_save
 -{
 -	my ($filename, $data, $more) = @_;
 -	my $FH;
 -
 -	$filename = doFilenameFixing($filename);
 -	return unless ($filename);
 -
 -	unless(open $FH, ">", $filename)
 -	{
 -		print "Can not open $filename";
 -		return;
 -	}
 -
 -	# Order by ref. Print ref and an id tag
 -	for my $win (sort {$a->{'refnum'} <=> $b->{'refnum'}} Irssi::windows())
 -	{
 -		my $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
 -		printf $FH "%d\t%s\n", $win->{'refnum'}, $id;
 -	}
 -	close $FH;
 -	print "Layout saved to $filename";
 -}
 -
 -# Load a list and use it to reorder
 -sub cmd_layout_load
 -{
 -	# Check filename supplied, exists and readable
 -	my ($filename, $data, $more) = @_;
 -	$filename = doFilenameFixing($filename);
 -	return unless ($filename);
 -
 -	return unless canReadFile($filename);
 -
 -	my @layout;
 -	my ($ref, $id, $FH);
 -
 -	# Pull the refnum and id
 -	unless(open $FH, "<", $filename)
 -	{
 -		print "Can not open file $filename.";
 -		return;
 -	}
 -	while (my $line = <$FH>)
 -	{
 -		chomp $line;
 -		my ($ref, $id) = split(/\t/, $line, 2);
 -		next unless ($ref and $id);
 -
 -		push @layout, {refnum => $ref, id => $id};
 -	}
 -	close $FH;
 -
 -	# For each layout item from the file, find the window and set it's ref to that number
 -	for my $position (sort {$a->{'refnum'} <=> $b->{'refnum'}} @layout)
 -	{
 -		for my $win (Irssi::windows())
 -		{
 -			$id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'} . ":" . $win->{'active'}->{'server'}->{'tag'};
 -			if ($id eq $position->{'id'})
 -			{
 -				$win->set_refnum($position->{'refnum'});
 -				last;
 -			}
 -		}
 -	}
 -}
 -
 -Irssi::settings_add_str('misc', 'layout_savepath', Irssi::get_irssi_dir());
 -
 -Irssi::command_bind( 'layout_save', 'cmd_layout_save' );
 -Irssi::command_bind( 'layout_load', 'cmd_layout_load' );
\ No newline at end of file +# Save window layout to an arbitrary file and load layouts upon demand +# Useful for being able to temporarily reorder your windows and then reverting to your "normal" layout +# Also useful as an easy way to reorder your windows +# +# A special thanks to billnye, Zed` and Bazerka for their help +# +# Usage: +#  /layout_save filename +#    Saves the layout to the textfile "filename.layout" +#  /layout_load filename +#    Loads the layout from the textfile "filename.layout" +# +# TODO: +#   Check the layout file for a number used twice +#   On script load, run a layout_load +#   On channel join, run load: channel joined +# + +use strict; +use Irssi; +use Data::Dumper; +use vars qw($VERSION %IRSSI); +use POSIX 'strftime'; + +%IRSSI = ( +    authors     => "Isaac Good", +    contact     => "irssi\@isaacgood.com", +    name        => "reorder", +    description => "Reordering windows based on a textfile.", +    license     => "GPL", +); +$VERSION = '1.0'; + +# Map user input to a valid filename +sub GetFilename +{ +    my ($filename) = @_; + +    # On no input, use a default filename. +    unless (length($filename)) +    { +        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +        $filename = POSIX::strftime("%y%m%d", $sec, $min, $hour, $mday, $mon, $year); +        # If you prefer not having datestamped filenames, uncomment: +        # $filename = "default"; +    } + +    # Use glob expansion to match things like ~/ +    my $glob = glob($filename); +    $filename = $glob if $glob; + +    # Only handle directories when using an absolute path. +    if ($filename =~ /\// and $filename !~ /^\//) +    { +        print "I don't like /'s in filenames. Unless you want to specify an absolute path."; +        return; +    } + +    # Add a file extension +    $filename .= '.layout' unless ($filename =~ /\.layout$/); + +    # Use get_irssi_dir() unless using an absolute path +    if ($filename !~ /\//) { +        my $path = Irssi::get_irssi_dir(); +        $path .= '/' unless ($path =~ /\/$/); +        $filename = $path . $filename; +    } + +    return $filename; +} + +# Check a filename exists and can be read. +sub CanReadFile +{ +    my ($filename) = @_; +    unless (-f $filename) +    { +        print "No such file $filename"; +        return 0; +    } +    unless (-r $filename) +    { +        print "Can not read file $filename"; +        return 0; +    } +    return 1; +} + +# Save the current layout to file +sub CmdLayoutSave +{ +    my ($filename, $data, $more) = @_; +    my $FH; + +    $filename = GetFilename($filename); +    return unless ($filename); + +    unless(open $FH, ">", $filename) +    { +        print "Can not open $filename"; +        return; +    } + +    # Order by ref. Print ref and an id tag +    for my $win (sort {$a->{'refnum'} <=> $b->{'refnum'}} Irssi::windows()) +    { +        my $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'}; +        my $tag = $win->{'active'}->{'server'}->{'tag'}; +        printf $FH "%d\t%s:%s\n", $win->{'refnum'}, $id, $tag; +    } +    close $FH; +    print "Layout saved to $filename"; +} + +# Load a list and use it to reorder +sub CmdLayoutLoad +{ +    my ($filename, $data, $more) = @_; +    $filename = GetFilename($filename); + +    return unless ($filename); +    return unless CanReadFile($filename); + +    my @layout; +    my ($ref, $id, $tag, $FH); + +    # Pull the refnum and id +    unless(open $FH, "<", $filename) +    { +        print "Can not open file $filename."; +        return; +    } +    while (my $line = <$FH>) +    { +        chomp $line; +        my ($ref, $id) = split(/\t/, $line, 2); +        next unless ($ref and $id); + +        push @layout, {refnum => $ref, id => $id}; +    } +    close $FH; + +    # For each layout item from the file, find the window and set it's ref to that number +    for my $position (sort {$a->{'refnum'} <=> $b->{'refnum'}} @layout) +    { +        for my $win (Irssi::windows()) +        { +            $id = $win->{'name'} ? $win->{'name'} : $win->{'active'}->{'name'}; +            $tag = $win->{'active'}->{'server'}->{'tag'}; +            $id .= ":" . $tag; +            if ($id eq $position->{'id'}) +            { +                $win->set_refnum($position->{'refnum'}); +                last; +            } +        } +    } +} + +Irssi::command_bind( 'layout_save', 'CmdLayoutSave' ); +Irssi::command_bind( 'layout_load', 'CmdLayoutLoad' ); | 
