Update ASCII plugin
This commit is contained in:
parent
23af1cca99
commit
655dbf7e58
|
@ -1,6 +1,9 @@
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=T8E56M6SP9JH2)
|
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=T8E56M6SP9JH2)
|
||||||
|
|
||||||
|
|
||||||
|
Try the plugin out in #ircart on EFnet. irc://irc.efnet.org/#ircart
|
||||||
|
|
||||||
|
|
||||||
<b>ASCII Art Plugin</b><br>
|
<b>ASCII Art Plugin</b><br>
|
||||||
Convert text to ASCII art or image URLs to ASCII/ANSI art. Covert ASCII art to PNG. Get ASCII weather, moon phase, and cryptocurrecy rates.
|
Convert text to ASCII art or image URLs to ASCII/ANSI art. Covert ASCII art to PNG. Get ASCII weather, moon phase, and cryptocurrecy rates.
|
||||||
|
|
||||||
|
@ -103,14 +106,15 @@ img --bg <0-99> <url> (set a background color)
|
||||||
img --fg <0-99> <url> (set a foreground color)
|
img --fg <0-99> <url> (set a foreground color)
|
||||||
img --fast <url> (use Euclidean color difference.)
|
img --fast <url> (use Euclidean color difference.)
|
||||||
img --slow <url> (use cie2000 color difference. best quality, default)
|
img --slow <url> (use cie2000 color difference. best quality, default)
|
||||||
img --dither <url> (dither source image to 256 colors. trades off quality for speed)
|
img --quantize <url> (quantize source image to 256 colors. trades off quality for speed)
|
||||||
|
img --no-quantize <url> (don't quantize source to 256 colors)
|
||||||
```
|
```
|
||||||
Here are some images using 99 color default output:
|
Here are some images using 99 color default output:
|
||||||
<br>
|
<br>
|
||||||
^ output of img https://i.imgur.com/aF9wihd.jpg (image command with default settings)
|
^ output of img https://i.imgur.com/aF9wihd.jpg (image command with default settings)
|
||||||
<br>
|
<br>
|
||||||
^ output of img --block https://i.imgur.com/aF9wihd.jpg (image command with colored space blocks)
|
^ output of img --block https://i.imgur.com/aF9wihd.jpg (image command with colored space blocks)
|
||||||
<br>
|
<br>
|
||||||
^ output of img --ascii https://i.imgur.com/aF9wihd.jpg (image command with colored space blocks)
|
^ output of img --ascii https://i.imgur.com/aF9wihd.jpg (image command with colored space blocks)
|
||||||
```
|
```
|
||||||
***************+*++++++++++++++++++++++++++++++++++++++=++=++========================---------------
|
***************+*++++++++++++++++++++++++++++++++++++++=++=++========================---------------
|
||||||
|
|
|
@ -17,14 +17,15 @@ import supybot.world as world
|
||||||
__version__ = ""
|
__version__ = ""
|
||||||
|
|
||||||
# XXX Replace this with an appropriate author or supybot.Author instance.
|
# XXX Replace this with an appropriate author or supybot.Author instance.
|
||||||
__author__ = supybot.authors.unknown
|
__author__ = supybot.Author('oddluck', 'oddluck',
|
||||||
|
'oddluck@riseup.net')
|
||||||
|
|
||||||
# This is a dictionary mapping supybot.Author instances to lists of
|
# This is a dictionary mapping supybot.Author instances to lists of
|
||||||
# contributions.
|
# contributions.
|
||||||
__contributors__ = {}
|
__contributors__ = {}
|
||||||
|
|
||||||
# This is a url where the most recent plugin package can be downloaded.
|
# This is a url where the most recent plugin package can be downloaded.
|
||||||
__url__ = ''
|
__url__ = 'https://github.com/oddluck/limnoria-plugins/'
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from . import plugin
|
from . import plugin
|
||||||
|
|
|
@ -38,8 +38,11 @@ registry.Boolean(False, _("""Turns on and off paste.ee support""")))
|
||||||
conf.registerChannelValue(ASCII, 'delay',
|
conf.registerChannelValue(ASCII, 'delay',
|
||||||
registry.Float(1.0, _("""Set the time delay betwen lines. Not currently implemented.""")))
|
registry.Float(1.0, _("""Set the time delay betwen lines. Not currently implemented.""")))
|
||||||
|
|
||||||
conf.registerChannelValue(ASCII, 'dither',
|
conf.registerChannelValue(ASCII, 'quantize',
|
||||||
registry.Boolean(True, _("""Enable dithering. Results in much faster rendering at a slight decrease in quality. Default: True""")))
|
registry.Boolean(False, _("""Enable quantizing to 256 colors before rendering. Results in much faster rendering at a slight decrease in quality. Default: False""")))
|
||||||
|
|
||||||
|
conf.registerChannelValue(ASCII, 'resize',
|
||||||
|
registry.Integer(3, _("""Set the resize algorithm. 0 = nearest, 1 = lanczos, 2 = bilinear, 3 = bicubic, 4 = box, 5 = hamming""")))
|
||||||
|
|
||||||
conf.registerChannelValue(ASCII, 'speed',
|
conf.registerChannelValue(ASCII, 'speed',
|
||||||
registry.String('Slow', _("""Set the speed of the color rendering. 'Slow' (default) to use CIEDE2000 color difference. 'Fast' to use Euclidean color difference.""")))
|
registry.String('Slow', _("""Set the speed of the color rendering. 'Slow' (default) to use CIEDE2000 color difference. 'Fast' to use Euclidean color difference.""")))
|
||||||
|
@ -51,7 +54,13 @@ conf.registerChannelValue(ASCII, 'asciiWidth',
|
||||||
registry.Integer(100, _("""Set the default column width for ascii art images""")))
|
registry.Integer(100, _("""Set the default column width for ascii art images""")))
|
||||||
|
|
||||||
conf.registerChannelValue(ASCII, 'blockWidth',
|
conf.registerChannelValue(ASCII, 'blockWidth',
|
||||||
registry.Integer(70, _("""Set the default column width for 1/2 and 1/4 block art images""")))
|
registry.Integer(80, _("""Set the default column width for 1/2 and 1/4 block art images""")))
|
||||||
|
|
||||||
conf.registerChannelValue(ASCII, 'colors',
|
conf.registerChannelValue(ASCII, 'colors',
|
||||||
registry.Integer(99, _("""Set the default number of colors to use. Options are 16 for colors 0-15 only, 83 for colors 16-98 only, and 99 (default) to use all available colors""")))
|
registry.Integer(99, _("""Set the default number of colors to use. Options are 16 for colors 0-15 only, 83 for colors 16-98 only, and 99 (default) to use all available colors""")))
|
||||||
|
|
||||||
|
conf.registerChannelValue(ASCII, 'fg',
|
||||||
|
registry.Integer(99, _("""Set the default foreground color for ascii art images. 0-98. 99 is disabled (default)""")))
|
||||||
|
|
||||||
|
conf.registerChannelValue(ASCII, 'bg',
|
||||||
|
registry.Integer(99, _("""Set the default background color for ascii art images. 0-98. 99 is disabled (default)""")))
|
||||||
|
|
507
ASCII/plugin.py
507
ASCII/plugin.py
|
@ -10,6 +10,7 @@ import supybot.utils as utils
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
import supybot.plugins as plugins
|
import supybot.plugins as plugins
|
||||||
import supybot.ircutils as ircutils
|
import supybot.ircutils as ircutils
|
||||||
|
import supybot.ircdb as ircdb
|
||||||
import supybot.callbacks as callbacks
|
import supybot.callbacks as callbacks
|
||||||
import supybot.ircmsgs as ircmsgs
|
import supybot.ircmsgs as ircmsgs
|
||||||
import os
|
import os
|
||||||
|
@ -343,15 +344,15 @@ class ASCII(callbacks.Plugin):
|
||||||
self.x256colors83 = [88,28,32,30,36,38,34,96,94,52,56,54,60,62,58,98,88,36,36,48,48,60,32,34,47,47,47,72,32,33,34,59,59,59,44,45,45,46,71,71,44,68,45,69,46,83,56,68,57,57,69,58,28,38,37,49,49,60,30,93,47,72,72,72,31,33,34,59,59,59,43,45,45,46,71,71,56,68,57,69,70,83,56,68,68,57,69,70,28,39,38,49,49,61,41,93,50,50,72,72,30,30,94,84,84,84,43,43,45,46,71,71,43,68,80,81,82,83,55,68,68,80,81,70,40,51,51,50,50,61,41,64,63,50,73,73,30,41,76,87,85,84,42,42,95,96,84,84,55,67,79,81,82,83,55,67,80,80,81,82,40,51,51,50,50,73,41,64,63,75,62,73,53,53,76,87,85,85,42,65,77,76,87,85,42,66,78,78,97,97,55,67,79,79,81,82,52,64,63,63,62,62,52,64,63,75,75,74,53,64,76,87,87,86,65,65,65,76,87,86,54,77,77,77,97,86,54,66,66,78,78,98,88,89,89,90,91,91,92,92,92,93,93,94,94,94,95,95,95,96,96,96,97,97,97,97]
|
self.x256colors83 = [88,28,32,30,36,38,34,96,94,52,56,54,60,62,58,98,88,36,36,48,48,60,32,34,47,47,47,72,32,33,34,59,59,59,44,45,45,46,71,71,44,68,45,69,46,83,56,68,57,57,69,58,28,38,37,49,49,60,30,93,47,72,72,72,31,33,34,59,59,59,43,45,45,46,71,71,56,68,57,69,70,83,56,68,68,57,69,70,28,39,38,49,49,61,41,93,50,50,72,72,30,30,94,84,84,84,43,43,45,46,71,71,43,68,80,81,82,83,55,68,68,80,81,70,40,51,51,50,50,61,41,64,63,50,73,73,30,41,76,87,85,84,42,42,95,96,84,84,55,67,79,81,82,83,55,67,80,80,81,82,40,51,51,50,50,73,41,64,63,75,62,73,53,53,76,87,85,85,42,65,77,76,87,85,42,66,78,78,97,97,55,67,79,79,81,82,52,64,63,63,62,62,52,64,63,75,75,74,53,64,76,87,87,86,65,65,65,76,87,86,54,77,77,77,97,86,54,66,66,78,78,98,88,89,89,90,91,91,92,92,92,93,93,94,94,94,95,95,95,96,96,96,97,97,97,97]
|
||||||
self.x16colors = {
|
self.x16colors = {
|
||||||
'30':'01',
|
'30':'01',
|
||||||
'31':'04',
|
'31':'05',
|
||||||
'32':'03',
|
'32':'03',
|
||||||
'33':'08',
|
'33':'07',
|
||||||
'34':'02',
|
'34':'02',
|
||||||
'35':'06',
|
'35':'06',
|
||||||
'36':'10',
|
'36':'10',
|
||||||
'37':'15',
|
'37':'15',
|
||||||
'30;1':'14',
|
'30;1':'14',
|
||||||
'31;1':'07',
|
'31;1':'04',
|
||||||
'32;1':'09',
|
'32;1':'09',
|
||||||
'33;1':'08',
|
'33;1':'08',
|
||||||
'34;1':'12',
|
'34;1':'12',
|
||||||
|
@ -359,15 +360,15 @@ class ASCII(callbacks.Plugin):
|
||||||
'36;1':'11',
|
'36;1':'11',
|
||||||
'37;1':'00',
|
'37;1':'00',
|
||||||
'40':'01',
|
'40':'01',
|
||||||
'41':'04',
|
'41':'05',
|
||||||
'42':'03',
|
'42':'03',
|
||||||
'43':'08',
|
'43':'07',
|
||||||
'44':'02',
|
'44':'02',
|
||||||
'45':'06',
|
'45':'06',
|
||||||
'46':'10',
|
'46':'10',
|
||||||
'47':'15',
|
'47':'15',
|
||||||
'40;1':'14',
|
'40;1':'14',
|
||||||
'41;1':'07',
|
'41;1':'04',
|
||||||
'42;1':'09',
|
'42;1':'09',
|
||||||
'43;1':'08',
|
'43;1':'08',
|
||||||
'44;1':'12',
|
'44;1':'12',
|
||||||
|
@ -464,6 +465,9 @@ class ASCII(callbacks.Plugin):
|
||||||
return self.matches[pixel]
|
return self.matches[pixel]
|
||||||
|
|
||||||
def rgb2lab (self, inputColor) :
|
def rgb2lab (self, inputColor) :
|
||||||
|
try:
|
||||||
|
return self.labmatches[inputColor]
|
||||||
|
except:
|
||||||
num = 0
|
num = 0
|
||||||
RGB = [0, 0, 0]
|
RGB = [0, 0, 0]
|
||||||
for value in inputColor :
|
for value in inputColor :
|
||||||
|
@ -499,82 +503,54 @@ class ASCII(callbacks.Plugin):
|
||||||
Lab [ 0 ] = round( L, 4 )
|
Lab [ 0 ] = round( L, 4 )
|
||||||
Lab [ 1 ] = round( a, 4 )
|
Lab [ 1 ] = round( a, 4 )
|
||||||
Lab [ 2 ] = round( b, 4 )
|
Lab [ 2 ] = round( b, 4 )
|
||||||
return Lab
|
self.labmatches[inputColor] = Lab
|
||||||
|
return self.labmatches[inputColor]
|
||||||
|
|
||||||
def ciede2000(self, color1, color2):
|
def ciede2000(self, lab1, lab2):
|
||||||
"""
|
""" CIEDE2000 color difference formula. https://peteroupc.github.io/colorgen.html"""
|
||||||
Calculates color difference according to the `CIEDE 2000`_ formula. This is
|
dl=lab2[0]-lab1[0]
|
||||||
the most accurate algorithm currently implemented but also the most complex
|
hl=lab1[0]+dl*0.5
|
||||||
and slowest. Like CIE1994 it is largely based in CIE L*C*h* space, but with
|
sqb1=lab1[2]*lab1[2]
|
||||||
several modifications to account for perceptual uniformity flaws.
|
sqb2=lab2[2]*lab2[2]
|
||||||
.. _CIEDE 2000: https://en.wikipedia.org/wiki/Color_difference#CIEDE2000
|
c1=math.sqrt(lab1[1]*lab1[1]+sqb1)
|
||||||
"""
|
c2=math.sqrt(lab2[1]*lab2[1]+sqb2)
|
||||||
# See WP article and Sharma 2005 for important implementation notes:
|
hc7=math.pow((c1+c2)*0.5,7)
|
||||||
# http://www.ece.rochester.edu/~gsharma/ciede2000/ciede2000noteCRNA.pdf
|
trc=math.sqrt(hc7/(hc7+6103515625))
|
||||||
#
|
t2=1.5-trc*0.5
|
||||||
# Yes, there's lots of locals; but this is easiest to understand as it's a
|
ap1=lab1[1]*t2
|
||||||
# near straight translation of the math
|
ap2=lab2[1]*t2
|
||||||
# pylint: disable=too-many-locals
|
c1=math.sqrt(ap1*ap1+sqb1)
|
||||||
C_ = (
|
c2=math.sqrt(ap2*ap2+sqb2)
|
||||||
math.sqrt(color1[1] ** 2 + color1[2] ** 2) +
|
dc=c2-c1
|
||||||
math.sqrt(color2[1] ** 2 + color2[2] ** 2)
|
hc=c1+dc*0.5
|
||||||
) / 2
|
hc7=math.pow(hc,7)
|
||||||
|
trc=math.sqrt(hc7/(hc7+6103515625))
|
||||||
G = (1 - math.sqrt(C_ ** 7 / (C_ ** 7 + 25 ** 7))) / 2
|
h1=math.atan2(lab1[2],ap1)
|
||||||
a1_prime = (1 + G) * color1[1]
|
if h1<0:
|
||||||
a2_prime = (1 + G) * color2[1]
|
h1=h1+math.pi*2
|
||||||
C1_prime = math.sqrt(a1_prime ** 2 + color1[2] ** 2)
|
h2=math.atan2(lab2[2],ap2)
|
||||||
C2_prime = math.sqrt(a2_prime ** 2 + color2[2] ** 2)
|
if h2<0:
|
||||||
L_ = (color1[0] + color2[0]) / 2
|
h2=h2+math.pi*2
|
||||||
C_ = (C1_prime + C2_prime) / 2
|
hdiff=h2-h1
|
||||||
h1 = (
|
hh=h1+h2
|
||||||
0.0 if color1[2] == a1_prime == 0 else
|
if abs(hdiff)>math.pi:
|
||||||
math.degrees(math.atan2(color1[2], a1_prime)) % 360
|
hh=hh+math.pi*2
|
||||||
)
|
if h2<=h1:
|
||||||
h2 = (
|
hdiff=hdiff+math.pi*2
|
||||||
0.0 if color2[2] == a2_prime == 0 else
|
|
||||||
math.degrees(math.atan2(color2[2], a2_prime)) % 360
|
|
||||||
)
|
|
||||||
if C1_prime * C2_prime == 0.0:
|
|
||||||
dh = 0.0
|
|
||||||
h_ = h1 + h2
|
|
||||||
elif abs(h1 - h2) <= 180:
|
|
||||||
dh = h2 - h1
|
|
||||||
h_ = (h1 + h2) / 2
|
|
||||||
else:
|
else:
|
||||||
if h2 > h1:
|
hdiff=hdiff-math.pi*2
|
||||||
dh = h2 - h1 - 360
|
hh=hh*0.5
|
||||||
else:
|
t2=1-0.17*math.cos(hh-math.pi/6)+0.24*math.cos(hh*2)
|
||||||
dh = h2 - h1 + 360
|
t2=t2+0.32*math.cos(hh*3+math.pi/30)
|
||||||
if h1 + h2 >= 360:
|
t2=t2-0.2*math.cos(hh*4-math.pi*63/180)
|
||||||
h_ = (h1 + h2 - 360) / 2
|
dh=2*math.sqrt(c1*c2)*math.sin(hdiff*0.5)
|
||||||
else:
|
sqhl=(hl-50)*(hl-50)
|
||||||
h_ = (h1 + h2 + 360) / 2
|
fl=dl/(1+(0.015*sqhl/math.sqrt(20+sqhl)))
|
||||||
|
fc=dc/(hc*0.045+1)
|
||||||
dL = color2[0] - color1[0]
|
fh=dh/(t2*hc*0.015+1)
|
||||||
dC = C2_prime - C1_prime
|
dt=30*math.exp(-math.pow(36*hh-55*math.pi,2)/(25*math.pi*math.pi))
|
||||||
dH = 2 * math.sqrt(C1_prime * C2_prime) * math.sin(math.radians(dh / 2))
|
r=-2*trc*math.sin(2*dt*math.pi/180)
|
||||||
T = (
|
return math.sqrt(fl*fl+fc*fc+fh*fh+r*fc*fh)
|
||||||
1 -
|
|
||||||
0.17 * math.cos(math.radians(h_ - 30)) +
|
|
||||||
0.24 * math.cos(math.radians(2 * h_)) +
|
|
||||||
0.32 * math.cos(math.radians(3 * h_ + 6)) -
|
|
||||||
0.20 * math.cos(math.radians(4 * h_ - 63))
|
|
||||||
)
|
|
||||||
SL = 1 + (0.015 * (L_ - 50) ** 2) / math.sqrt(20 + (L_ - 50) ** 2)
|
|
||||||
SC = 1 + 0.045 * C_
|
|
||||||
SH = 1 + 0.015 * C_ * T
|
|
||||||
RT = (
|
|
||||||
-2 * math.sqrt(C_ ** 7 / (C_ ** 7 + 25 ** 7)) *
|
|
||||||
math.sin(math.radians(60 * math.exp(-(((h_ - 275) / 25) ** 2))))
|
|
||||||
)
|
|
||||||
delta_e = math.sqrt(
|
|
||||||
(dL / SL) ** 2 +
|
|
||||||
(dC / SC) ** 2 +
|
|
||||||
(dH / SH) ** 2 +
|
|
||||||
RT * (dC / SC) * (dH / SH)
|
|
||||||
)
|
|
||||||
return delta_e
|
|
||||||
|
|
||||||
def distance(self, c1, c2, speed):
|
def distance(self, c1, c2, speed):
|
||||||
if speed == 'fast':
|
if speed == 'fast':
|
||||||
|
@ -619,12 +595,12 @@ class ASCII(callbacks.Plugin):
|
||||||
continue
|
continue
|
||||||
elif int(ansi[i]) > 29 and int(ansi[i]) < 38:
|
elif int(ansi[i]) > 29 and int(ansi[i]) < 38:
|
||||||
if effect == 1 or ansi[-1] == '1':
|
if effect == 1 or ansi[-1] == '1':
|
||||||
x16color2 = self.x16colors['{0};1'.format(ansi[i])]
|
x16color1 = self.x16colors['{0};1'.format(ansi[i])]
|
||||||
effect = None
|
effect = None
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
x16color2 = self.x16colors[ansi[i]]
|
x16color1 = self.x16colors[ansi[i]]
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
elif int(ansi[i]) > 39 and int(ansi[i]) < 48:
|
elif int(ansi[i]) > 39 and int(ansi[i]) < 48:
|
||||||
|
@ -690,9 +666,11 @@ class ASCII(callbacks.Plugin):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def ansi2irc(self, output):
|
def ansi2irc(self, output):
|
||||||
output = output.replace('\x1b[0m\x1b', '\x1b')
|
output = output.replace('\x1b(B\x1b[m', '\x1b[0m')
|
||||||
|
output = output.replace('\x1b\x1b', '\x1b')
|
||||||
output = re.sub(r'\x1B\[[0-?]*[ -/]*[@-~]', lambda m: self.process_ansi(m.group(0)), output)
|
output = re.sub(r'\x1B\[[0-?]*[ -/]*[@-~]', lambda m: self.process_ansi(m.group(0)), output)
|
||||||
output = re.sub('\x0399,(\d\d)\x03(\d\d)', '\x03\g<2>,\g<1>', output)
|
output = re.sub('\x0399,(\d\d)\x03(\d\d)', '\x03\g<2>,\g<1>', output)
|
||||||
|
output = output.replace('\x0F\x03', '\x03')
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def png(self, irc, msg, args, optlist, url):
|
def png(self, irc, msg, args, optlist, url):
|
||||||
|
@ -718,7 +696,11 @@ class ASCII(callbacks.Plugin):
|
||||||
else:
|
else:
|
||||||
irc.reply("Invalid file type.", private=False, notice=False)
|
irc.reply("Invalid file type.", private=False, notice=False)
|
||||||
return
|
return
|
||||||
|
try:
|
||||||
file = file.content.decode()
|
file = file.content.decode()
|
||||||
|
except:
|
||||||
|
file = file.content.decode('cp437')
|
||||||
|
file = re.sub('(\x03(\d+).*)\x03,', '\g<1>\x03\g<2>,', file).replace('\r\n','\n')
|
||||||
im, x, y = self.renderImage(file, 18, bg, fg)
|
im, x, y = self.renderImage(file, 18, bg, fg)
|
||||||
path = os.path.dirname(os.path.abspath(__file__))
|
path = os.path.dirname(os.path.abspath(__file__))
|
||||||
filepath = "{0}/tmp/tldr.png".format(path)
|
filepath = "{0}/tmp/tldr.png".format(path)
|
||||||
|
@ -795,7 +777,7 @@ class ASCII(callbacks.Plugin):
|
||||||
fontlist = wrap(fontlist)
|
fontlist = wrap(fontlist)
|
||||||
|
|
||||||
def img(self, irc, msg, args, channel, optlist, url):
|
def img(self, irc, msg, args, channel, optlist, url):
|
||||||
"""[<#channel>] [--delay #.#] [--w <###>] [--s <#.#] [--16] [--99] [--83] [--ascii] [--block] [--1/2] [--1/4] [--chars <text>] [--ramp <text>] [--bg <0-98>] [--fg <0-98>] [--no-color] [--invert] [--dither] [--no-dither] <url>
|
"""[<#channel>] [--delay #.#] [--w <###>] [--s <#.#] [--16] [--99] [--83] [--ascii] [--block] [--1/2] [--chars <text>] [--ramp <text>] [--bg <0-98>] [--fg <0-98>] [--no-color] [--invert] <url>
|
||||||
Image to ASCII Art.
|
Image to ASCII Art.
|
||||||
--w columns.
|
--w columns.
|
||||||
--s saturation (1.0).
|
--s saturation (1.0).
|
||||||
|
@ -804,7 +786,6 @@ class ASCII(callbacks.Plugin):
|
||||||
--83 colors 16-98.
|
--83 colors 16-98.
|
||||||
--ascii color ascii.
|
--ascii color ascii.
|
||||||
--block space block.
|
--block space block.
|
||||||
--1/4 for 1/4 block.
|
|
||||||
--1/2 for 1/2 block
|
--1/2 for 1/2 block
|
||||||
--chars <TEXT> color text.
|
--chars <TEXT> color text.
|
||||||
--ramp <TEXT> set ramp (".:-=+*#%@").
|
--ramp <TEXT> set ramp (".:-=+*#%@").
|
||||||
|
@ -812,11 +793,12 @@ class ASCII(callbacks.Plugin):
|
||||||
--fg <0-99> set fg.
|
--fg <0-99> set fg.
|
||||||
--no-color greyscale ascii.
|
--no-color greyscale ascii.
|
||||||
--invert inverts ramp.
|
--invert inverts ramp.
|
||||||
--dither to reduce source colors.
|
|
||||||
--no-dither for no color reduction.
|
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
gscale = "\xa0"
|
gscale = "\xa0"
|
||||||
if '16' in optlist:
|
if '16' in optlist:
|
||||||
|
@ -837,20 +819,20 @@ class ASCII(callbacks.Plugin):
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
else:
|
else:
|
||||||
delay = self.registryValue('delay', msg.args[0])
|
delay = self.registryValue('delay', msg.args[0])
|
||||||
if 'dither' in optlist:
|
if 'quantize' in optlist:
|
||||||
dither = True
|
quantize = True
|
||||||
elif 'no-dither' in optlist:
|
elif 'no-quantize' in optlist:
|
||||||
dither = False
|
quantize = False
|
||||||
else:
|
else:
|
||||||
dither = self.registryValue('dither', msg.args[0])
|
quantize = self.registryValue('quantize', msg.args[0])
|
||||||
if 'bg' in optlist:
|
if 'bg' in optlist:
|
||||||
bg = optlist.get('bg')
|
bg = optlist.get('bg')
|
||||||
else:
|
else:
|
||||||
bg = 1
|
bg = self.registryValue('bg', msg.args[0])
|
||||||
if 'fg' in optlist:
|
if 'fg' in optlist:
|
||||||
fg = optlist.get('fg')
|
fg = optlist.get('fg')
|
||||||
else:
|
else:
|
||||||
fg = 99
|
fg = self.registryValue('fg', msg.args[0])
|
||||||
if 'chars' in optlist:
|
if 'chars' in optlist:
|
||||||
type = 'ascii'
|
type = 'ascii'
|
||||||
gscale = optlist.get('chars')
|
gscale = optlist.get('chars')
|
||||||
|
@ -863,8 +845,6 @@ class ASCII(callbacks.Plugin):
|
||||||
elif 'ascii' in optlist:
|
elif 'ascii' in optlist:
|
||||||
type = 'ascii'
|
type = 'ascii'
|
||||||
gscale = ".'`^\":;Il!i><~+_-?][}{1)(|\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"
|
gscale = ".'`^\":;Il!i><~+_-?][}{1)(|\/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$"
|
||||||
elif '1/4' in optlist:
|
|
||||||
type = '1/4'
|
|
||||||
elif '1/2' in optlist:
|
elif '1/2' in optlist:
|
||||||
type = '1/2'
|
type = '1/2'
|
||||||
elif 'block' in optlist:
|
elif 'block' in optlist:
|
||||||
|
@ -890,8 +870,6 @@ class ASCII(callbacks.Plugin):
|
||||||
cols = self.registryValue('asciiWidth', msg.args[0])
|
cols = self.registryValue('asciiWidth', msg.args[0])
|
||||||
else:
|
else:
|
||||||
cols = self.registryValue('blockWidth', msg.args[0])
|
cols = self.registryValue('blockWidth', msg.args[0])
|
||||||
if type == '1/4':
|
|
||||||
cols = cols * 2
|
|
||||||
if 's' in optlist:
|
if 's' in optlist:
|
||||||
s = float(optlist.get('s'))
|
s = float(optlist.get('s'))
|
||||||
path = os.path.dirname(os.path.abspath(__file__))
|
path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -912,7 +890,11 @@ class ASCII(callbacks.Plugin):
|
||||||
# open image and convert to grayscale
|
# open image and convert to grayscale
|
||||||
image = Image.open(filename)
|
image = Image.open(filename)
|
||||||
if image.mode == 'RGBA':
|
if image.mode == 'RGBA':
|
||||||
image = Image.alpha_composite(Image.new("RGBA", image.size, self.rgbColors[bg] + (255,)), image)
|
if bg == 99:
|
||||||
|
newbg = 1
|
||||||
|
else:
|
||||||
|
newbg = bg
|
||||||
|
image = Image.alpha_composite(Image.new("RGBA", image.size, self.rgbColors[newbg] + (255,)), image)
|
||||||
if image.mode != 'RGB':
|
if image.mode != 'RGB':
|
||||||
image = image.convert('RGB')
|
image = image.convert('RGB')
|
||||||
try:
|
try:
|
||||||
|
@ -931,16 +913,20 @@ class ASCII(callbacks.Plugin):
|
||||||
h = w/scale
|
h = w/scale
|
||||||
# compute number of rows
|
# compute number of rows
|
||||||
rows = int(H/h)
|
rows = int(H/h)
|
||||||
image = ImageOps.autocontrast(image)
|
if 'resize' in optlist:
|
||||||
|
resize = optlist.get('resize')
|
||||||
|
else:
|
||||||
|
resize = self.registryValue('resize', msg.args[0])
|
||||||
if type != 'no-color':
|
if type != 'no-color':
|
||||||
image2 = image.resize((cols, rows), Image.LANCZOS)
|
image2 = image.resize((cols, rows), resize)
|
||||||
if 's' in optlist:
|
if 's' in optlist:
|
||||||
image2 = ImageEnhance.Color(image2).enhance(s)
|
image2 = ImageEnhance.Color(image2).enhance(s)
|
||||||
if dither:
|
if quantize:
|
||||||
image2 = image2.convert('P', palette=Image.ADAPTIVE)
|
image2 = image2.quantize(dither=None)
|
||||||
image2 = image2.convert('RGB')
|
image2 = image2.convert('RGB')
|
||||||
colormap = np.array(image2)
|
colormap = np.array(image2)
|
||||||
self.matches = {}
|
self.matches = {}
|
||||||
|
self.labmatches = {}
|
||||||
# ascii image is a list of character strings
|
# ascii image is a list of character strings
|
||||||
aimg = []
|
aimg = []
|
||||||
if type == '1/2':
|
if type == '1/2':
|
||||||
|
@ -948,154 +934,111 @@ class ASCII(callbacks.Plugin):
|
||||||
for j in range(0, rows - 1, 2):
|
for j in range(0, rows - 1, 2):
|
||||||
# append an empty string
|
# append an empty string
|
||||||
aimg.append("")
|
aimg.append("")
|
||||||
old_color = "99,99"
|
old_color1 = "99"
|
||||||
|
old_color2 = "99"
|
||||||
|
old_char = None
|
||||||
for i in range(cols):
|
for i in range(cols):
|
||||||
color1 = '%02d' % self.getColor(colormap[j][i].tolist(), speed)
|
color1 = '%02d' % self.getColor(colormap[j][i].tolist(), speed)
|
||||||
color2 = '%02d' % self.getColor(colormap[j+1][i].tolist(), speed)
|
color2 = '%02d' % self.getColor(colormap[j+1][i].tolist(), speed)
|
||||||
color = "{0},{1}".format(color1, color2)
|
|
||||||
if color != old_color:
|
|
||||||
if color1 == color2:
|
if color1 == color2:
|
||||||
gsval = " "
|
gsval = " "
|
||||||
color = "0,{0}".format(color1)
|
|
||||||
else:
|
else:
|
||||||
gsval = "▀"
|
gsval = "▀"
|
||||||
alt_gsval = "▄"
|
if color1 == old_color1 and color2 == old_color2:
|
||||||
if gsval != " " and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]) and 'tops' not in optlist:
|
aimg[k] += gsval
|
||||||
aimg[k] += alt_gsval
|
old_char = gsval
|
||||||
elif gsval == " " and "{0}".format(color1) == "{0}".format(old_color.split(',')[1]):
|
elif gsval == " " and color1 == old_color2:
|
||||||
aimg[k] += " "
|
aimg[k] += " "
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval == " " and color1 == old_color1 and old_char == '█':
|
||||||
|
aimg[k] = aimg[k][:-1]
|
||||||
|
aimg[k] += "\x0301,{0} ".format(color1)
|
||||||
|
old_color1 = "01"
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval == " " and color1 == old_color1 and old_char == '^█':
|
||||||
|
aimg[k] = aimg[k][:-4]
|
||||||
|
aimg[k] += "\x0301,{0} ".format(color1)
|
||||||
|
old_color1 = "01"
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval == " " and color1 == old_color1 and old_char == "^^▀" and 'tops' not in optlist:
|
||||||
|
aimg[k] = aimg[k][:-7]
|
||||||
|
aimg[k] += "\x03{0},{1}▄ ".format(old_color2, color1)
|
||||||
|
old_color1 = old_color2
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval == " " and color1 == old_color1 and old_char != '█' and 'tops' not in optlist:
|
||||||
|
aimg[k] += "█"
|
||||||
|
old_char = '█'
|
||||||
|
elif gsval == " " and 'tops' not in optlist:
|
||||||
|
aimg[k] += "\x03{0}█".format(color1)
|
||||||
|
old_color1 = color1
|
||||||
|
old_char = '^█'
|
||||||
|
elif gsval != " " and color1 == old_color1 and old_char == '^█' and 'tops' not in optlist:
|
||||||
|
aimg[k] = aimg[k][:-4]
|
||||||
|
aimg[k] += "\x03{0},{1} ▄".format(color2, color1)
|
||||||
|
old_color1 = color2
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = '▄'
|
||||||
|
elif gsval != " " and color2 == old_color1 and old_char == '^█':
|
||||||
|
aimg[k] = aimg[k][:-4]
|
||||||
|
aimg[k] += "\x03{0},{1} ▀".format(color1, color2)
|
||||||
|
old_color1 = color1
|
||||||
|
old_color2 = color2
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval != " " and color1 == old_color2 and color2 == old_color1 and old_char == "^^▀" and 'tops' not in optlist:
|
||||||
|
aimg[k] = aimg[k][:-7]
|
||||||
|
aimg[k] += "\x03{0},{1}▄▀".format(color1, color2)
|
||||||
|
old_color1 = color1
|
||||||
|
old_color2 = color2
|
||||||
|
old_char = gsval
|
||||||
|
elif gsval != " " and color1 == old_color1 and color2 != old_color2 and old_char == "^^▀" and 'tops' not in optlist:
|
||||||
|
aimg[k] = aimg[k][:-7]
|
||||||
|
aimg[k] += "\x03{0},{1}▄\x03{2}▄".format(old_color2, color1, color2)
|
||||||
|
old_color1 = color2
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = '▄'
|
||||||
|
elif gsval != " " and color1 == old_color1 and color2 != old_color2 and old_char == "^▀" and 'tops' not in optlist:
|
||||||
|
aimg[k] = aimg[k][:-4]
|
||||||
|
aimg[k] += "\x03{0},{1}▄\x03{2}▄".format(old_color2, color1, color2)
|
||||||
|
old_color1 = color2
|
||||||
|
old_color2 = color1
|
||||||
|
old_char = '▄'
|
||||||
|
elif gsval != " " and color1 == old_color2 and color2 == old_color1 and 'tops' not in optlist:
|
||||||
|
aimg[k] += "▄"
|
||||||
|
old_char = '▄'
|
||||||
|
elif gsval != " " and color1 == old_color2 and 'tops' not in optlist:
|
||||||
|
aimg[k] += "\x03{0}▄".format(color2)
|
||||||
|
old_color1 = color2
|
||||||
|
old_char = '▄'
|
||||||
|
elif color1 != old_color1 and color2 == old_color2:
|
||||||
|
aimg[k] += "\x03{0}{1}".format(color1, gsval)
|
||||||
|
old_color1 = color1
|
||||||
|
if gsval == ' ':
|
||||||
|
old_char = gsval
|
||||||
else:
|
else:
|
||||||
aimg[k] += "\x03{0}{1}".format(color, gsval)
|
old_char = '^▀'
|
||||||
old_color = color
|
|
||||||
else:
|
else:
|
||||||
if color1 == color2:
|
aimg[k] += "\x03{0},{1}{2}".format(color1, color2, gsval)
|
||||||
aimg[k] += " "
|
old_color1 = color1
|
||||||
|
old_color2 = color2
|
||||||
|
if gsval == ' ':
|
||||||
|
old_char = gsval
|
||||||
else:
|
else:
|
||||||
aimg[k] += "▀"
|
old_char = '^^▀'
|
||||||
for i in range(0,98):
|
if 'tops' in optlist:
|
||||||
i = '%02d' % i
|
aimg[k] = re.sub("\x03\d\d,(\d\d\s+\x03)", "\x0301,\g<1>", aimg[k])
|
||||||
aimg[k] = re.sub("\x030,{0}(\s+)\x03(\d\d),{0}".format(i), "\x03\g<2>,{0}\g<1>".format(i), aimg[k])
|
aimg[k] = re.sub("\x03\d\d,(\d\d\s+$)", "\x0301,\g<1>", aimg[k])
|
||||||
for i in range(0,98):
|
aimg[k] = re.sub("\x03\d\d,(\d\d\s\x03)", "\x0301,\g<1>", aimg[k])
|
||||||
i = '%02d' % i
|
aimg[k] = re.sub("\x0301,(\d\d)(\s+)\x03(\d\d)([^,])", "\x03\g<3>,\g<1>\g<2>\g<4>", aimg[k])
|
||||||
aimg[k] = aimg[k].replace("{0}".format(i), "{0}".format(int(i)))
|
|
||||||
k += 1
|
|
||||||
elif type == '1/4':
|
|
||||||
k = 0
|
|
||||||
for j in range(0, rows - 1, 2):
|
|
||||||
# append an empty string
|
|
||||||
aimg.append("")
|
|
||||||
old_color = "99,99"
|
|
||||||
for i in range(0, cols - 1, 2):
|
|
||||||
color1 = '%02d' % self.getColor(colormap[j][i].tolist(), speed)
|
|
||||||
color2 = '%02d' % self.getColor(colormap[j+1][i].tolist(), speed)
|
|
||||||
color3 = '%02d' % self.getColor(colormap[j][i+1].tolist(), speed)
|
|
||||||
color4 = '%02d' % self.getColor(colormap[j+1][i+1].tolist(), speed)
|
|
||||||
if color1 == color2 and color1 == color3 and color1 == color4:
|
|
||||||
gsval = " "
|
|
||||||
color = "0,{0}".format(color1)
|
|
||||||
elif color1 == color4 and color2 == color3:
|
|
||||||
gsval = "▚"
|
|
||||||
color = "{0},{1}".format(color1, color2)
|
|
||||||
elif color1 == color2 and color1 == color3 and color1 != color4:
|
|
||||||
gsval = "▛"
|
|
||||||
color = "{0},{1}".format(color1, color4)
|
|
||||||
elif color3 == color4 and color2 == color4 and color3 != color1:
|
|
||||||
gsval = "▟"
|
|
||||||
color = "{0},{1}".format(color2, color1)
|
|
||||||
elif color1 == color2 and color1 == color4 and color1 != color3:
|
|
||||||
gsval = "▙"
|
|
||||||
color = "{0},{1}".format(color1, color3)
|
|
||||||
elif color1 == color3 and color1 == color4 and color1 != color2:
|
|
||||||
gsval = "▜"
|
|
||||||
color = "{0},{1}".format(color1, color2)
|
|
||||||
elif color1 == color3 and color2 == color4 and color1 != color2 and color3 != color4:
|
|
||||||
gsval = "▀"
|
|
||||||
color = "{0},{1}".format(color1, color4)
|
|
||||||
elif color1 == color2 and color3 == color4 and color1 != color3 and color2 != color4:
|
|
||||||
gsval = "▌"
|
|
||||||
color = "{0},{1}".format(color1, color4)
|
|
||||||
else:
|
|
||||||
row1 = '%02d' % self.getColor(np.average([tuple(colormap[j][i].tolist()), tuple(colormap[j][i+1].tolist())], axis=0).tolist(), speed)
|
|
||||||
row2 = '%02d' % self.getColor(np.average([tuple(colormap[j+1][i+1].tolist()), tuple(colormap[j][i+1].tolist())], axis=0).tolist(), speed)
|
|
||||||
if row2 == color1 and row2 != color3:
|
|
||||||
gsval = "▙"
|
|
||||||
color = "{0},{1}".format(row2, color3)
|
|
||||||
elif row1 == color2 and row1 != color4:
|
|
||||||
gsval = "▛"
|
|
||||||
color = "{0},{1}".format(row1, color4)
|
|
||||||
elif row2 == color3 and row2 != color1:
|
|
||||||
gsval = "▟"
|
|
||||||
color = "{0},{1}".format(row2, color1)
|
|
||||||
elif row1 == color4 and row1 != color2:
|
|
||||||
gsval = "▜"
|
|
||||||
color = "{0},{1}".format(row1, color2)
|
|
||||||
else:
|
|
||||||
col1 = '%02d' % self.getColor(np.average([tuple(colormap[j][i].tolist()), tuple(colormap[j+1][i].tolist())], axis=0).tolist(), speed)
|
|
||||||
col2 = '%02d' % self.getColor(np.average([tuple(colormap[j][i+1].tolist()), tuple(colormap[j+1][i+1].tolist())], axis=0).tolist(), speed)
|
|
||||||
if col1 == color4 and col1 != color3:
|
|
||||||
gsval = "▙"
|
|
||||||
color = "{0},{1}".format(col1, color3)
|
|
||||||
elif col1 == color3 and col1 != color4:
|
|
||||||
gsval = "▛"
|
|
||||||
color = "{0},{1}".format(col1, color4)
|
|
||||||
elif col2 == color2 and col2 != color1:
|
|
||||||
gsval = "▟"
|
|
||||||
color = "{0},{1}".format(col2, color1)
|
|
||||||
elif col2 == color1 and col2 != color2:
|
|
||||||
gsval = "▜"
|
|
||||||
color = "{0},{1}".format(col2, color2)
|
|
||||||
elif row1 != row2:
|
|
||||||
gsval = "▀"
|
|
||||||
color = "{0},{1}".format(row1, row2)
|
|
||||||
elif col1 != col2:
|
|
||||||
gsval = "▌"
|
|
||||||
color = "{0},{1}".format(col1, col2)
|
|
||||||
elif row1 == row2:
|
|
||||||
gsval = " "
|
|
||||||
color = "0,{0}".format(row1)
|
|
||||||
elif col1 == col2:
|
|
||||||
gsval = " "
|
|
||||||
color = "0,{0}".format(col1)
|
|
||||||
if color != old_color:
|
|
||||||
if gsval == " " and "{0}".format(color.split(',')[1]) == "{0}".format(old_color.split(',')[1]):
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▚" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▞"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▀" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▄"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▌" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▐"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▛" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▟"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▟" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▛"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▜" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▙"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
elif gsval == "▙" and color == "{0},{1}".format(old_color.split(',')[1], old_color.split(',')[0]):
|
|
||||||
gsval = "▜"
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
else:
|
|
||||||
old_color = color
|
|
||||||
# append char to string
|
|
||||||
aimg[k] += "\x03{0}{1}".format(color, gsval)
|
|
||||||
else:
|
|
||||||
aimg[k] += "{0}".format(gsval)
|
|
||||||
for i in range(0,98):
|
|
||||||
i = '%02d' % i
|
|
||||||
aimg[k] = re.sub("\x030,{0}(\s+)\x03(\d\d),{0}".format(i), "\x03\g<2>,{0}\g<1>".format(i), aimg[k])
|
|
||||||
for i in range(0,98):
|
for i in range(0,98):
|
||||||
i = '%02d' % i
|
i = '%02d' % i
|
||||||
aimg[k] = aimg[k].replace("{0}".format(i), "{0}".format(int(i)))
|
aimg[k] = aimg[k].replace("{0}".format(i), "{0}".format(int(i)))
|
||||||
k += 1
|
k += 1
|
||||||
else:
|
else:
|
||||||
if 'chars' not in optlist and gscale != '\xa0':
|
if 'chars' not in optlist and gscale != '\xa0':
|
||||||
image = image.resize((cols, rows), Image.LANCZOS)
|
image = image.resize((cols, rows), resize)
|
||||||
image = image.convert('L')
|
image = image.convert('L')
|
||||||
lumamap = np.array(image)
|
lumamap = np.array(image)
|
||||||
# generate list of dimensions
|
# generate list of dimensions
|
||||||
|
@ -1121,33 +1064,27 @@ class ASCII(callbacks.Plugin):
|
||||||
else:
|
else:
|
||||||
gsval = '\xa0'
|
gsval = '\xa0'
|
||||||
# get color value
|
# get color value
|
||||||
if type != 'no-color' and i == 0:
|
if type != 'no-color' and gscale != '\xa0' and i == 0:
|
||||||
color = self.getColor(colormap[j][i].tolist(), speed)
|
color = self.getColor(colormap[j][i].tolist(), speed)
|
||||||
old_color = color
|
old_color = color
|
||||||
if 'bg' not in optlist:
|
if bg != 99:
|
||||||
|
color = "{0},{1}".format(color, "{:02d}".format(int(bg)))
|
||||||
if gsval != '\xa0':
|
if gsval != '\xa0':
|
||||||
if gsval.isdigit():
|
|
||||||
color = "{:02d}".format(int(color))
|
|
||||||
aimg[j] += "\x03{0}{1}".format(color, gsval)
|
aimg[j] += "\x03{0}{1}".format(color, gsval)
|
||||||
else:
|
|
||||||
aimg[j] += "\x03{0}{1}".format(int(color), gsval)
|
|
||||||
else:
|
|
||||||
aimg[j] += "\x030,{0} ".format(int(color))
|
|
||||||
else:
|
|
||||||
if gsval != '\xa0':
|
|
||||||
if gsval.isdigit():
|
|
||||||
newbg = "{:02d}".format(int(bg))
|
|
||||||
aimg[j] += "\x03{0},{1}{2}".format(int(color), newbg, gsval)
|
|
||||||
else:
|
|
||||||
aimg[j] += "\x03{0},{1}{2}".format(int(color), int(bg), gsval)
|
|
||||||
else:
|
else:
|
||||||
aimg[j] += "\x030,{0} ".format(int(color))
|
aimg[j] += "\x030,{0} ".format(int(color))
|
||||||
|
elif type == 'no-color' and i == 0:
|
||||||
|
if bg != 99 and fg != 99:
|
||||||
|
aimg[j] += "\x03{0},{1}{2}".format("{:02d}".format(int(fg)), "{:02d}".format(int(bg)), gsval)
|
||||||
|
elif fg != 99:
|
||||||
|
aimg[j] += "\x03{0}{1}".format("{:02d}".format(int(fg)), gsval)
|
||||||
|
elif bg != 99:
|
||||||
|
aimg[j] += "\x03{0},{1}{2}".format("{:02d}".format(int(fg)), "{:02d}".format(int(bg)), gsval)
|
||||||
elif type != 'no-color' and gsval != ' ':
|
elif type != 'no-color' and gsval != ' ':
|
||||||
color = self.getColor(colormap[j][i].tolist(), speed)
|
color = self.getColor(colormap[j][i].tolist(), speed)
|
||||||
if color != old_color:
|
if color != old_color:
|
||||||
old_color = color
|
old_color = color
|
||||||
# append ascii char to string
|
# append ascii char to string
|
||||||
if 'bg' not in optlist:
|
|
||||||
if gsval != '\xa0':
|
if gsval != '\xa0':
|
||||||
if gsval.isdigit():
|
if gsval.isdigit():
|
||||||
color = "{:02d}".format(int(color))
|
color = "{:02d}".format(int(color))
|
||||||
|
@ -1156,33 +1093,14 @@ class ASCII(callbacks.Plugin):
|
||||||
aimg[j] += "\x03{0}{1}".format(int(color), gsval)
|
aimg[j] += "\x03{0}{1}".format(int(color), gsval)
|
||||||
else:
|
else:
|
||||||
aimg[j] += "\x030,{0} ".format(int(color))
|
aimg[j] += "\x030,{0} ".format(int(color))
|
||||||
else:
|
|
||||||
if gsval != '\xa0':
|
|
||||||
if gsval.isdigit():
|
|
||||||
newbg = "{:02d}".format(int(bg))
|
|
||||||
aimg[j] += "\x03{0},{1}{2}".format(int(color), newbg, gsval)
|
|
||||||
else:
|
|
||||||
aimg[j] += "\x03{0},{1}{2}".format(int(color), int(bg), gsval)
|
|
||||||
else:
|
|
||||||
aimg[j] += "\x030,{0} ".format(int(color))
|
|
||||||
else:
|
else:
|
||||||
aimg[j] += "{0}".format(gsval)
|
aimg[j] += "{0}".format(gsval)
|
||||||
else:
|
else:
|
||||||
aimg[j] += "{0}".format(gsval)
|
aimg[j] += "{0}".format(gsval)
|
||||||
# return txt image
|
|
||||||
output = aimg
|
output = aimg
|
||||||
paste = ""
|
paste = ""
|
||||||
self.stopped[msg.args[0]] = False
|
self.stopped[msg.args[0]] = False
|
||||||
for line in output:
|
for line in output:
|
||||||
if type == 'no-color' and 'fg' in optlist and 'bg' in optlist:
|
|
||||||
newbg = "{:02d}".format(int(bg))
|
|
||||||
line = "\x03{0},{1}{2}".format(int(fg), newbg, line)
|
|
||||||
elif type == 'no-color' and 'fg' in optlist:
|
|
||||||
newfg = "{:02d}".format(int(fg))
|
|
||||||
line = "\x03{0}{1}".format(newfg, line)
|
|
||||||
elif type == 'no-color' and 'bg' in optlist:
|
|
||||||
newbg = "{:02d}".format(int(bg))
|
|
||||||
line = "\x0399,{0}{1}".format(newbg, line)
|
|
||||||
if self.registryValue('pasteEnable', msg.args[0]):
|
if self.registryValue('pasteEnable', msg.args[0]):
|
||||||
paste += line + "\n"
|
paste += line + "\n"
|
||||||
if not self.stopped[msg.args[0]]:
|
if not self.stopped[msg.args[0]]:
|
||||||
|
@ -1190,7 +1108,7 @@ class ASCII(callbacks.Plugin):
|
||||||
irc.reply(line, prefixNick=False, noLengthCheck=True, private=False, notice=False, to=channel)
|
irc.reply(line, prefixNick=False, noLengthCheck=True, private=False, notice=False, to=channel)
|
||||||
if self.registryValue('pasteEnable', msg.args[0]):
|
if self.registryValue('pasteEnable', msg.args[0]):
|
||||||
irc.reply(self.doPaste(url, paste), private=False, notice=False, to=channel)
|
irc.reply(self.doPaste(url, paste), private=False, notice=False, to=channel)
|
||||||
img = wrap(img,[optional('channel'), getopts({'w':'int', 'invert':'', 'fast':'', 'slow':'', '16':'', '99':'', '83':'', 'delay':'float', 'dither':'', 'no-dither':'', 'chars':'text', 'bg':'int', 'fg':'int', 'ramp':'text', 'no-color':'', 'block':'', 'ascii':'', '1/4':'', '1/2':'', 's':'float', 'tops':''}), ('text')])
|
img = wrap(img,[optional('channel'), getopts({'w':'int', 'invert':'', 'fast':'', 'slow':'', '16':'', '99':'', '83':'', 'delay':'float', 'resize':'int', 'quantize':'', 'no-quantize':'', 'chars':'text', 'bg':'int', 'fg':'int', 'ramp':'text', 'no-color':'', 'block':'', 'ascii':'', '1/2':'', 's':'float', 'tops':''}), ('text')])
|
||||||
|
|
||||||
def scroll(self, irc, msg, args, channel, optlist, url):
|
def scroll(self, irc, msg, args, channel, optlist, url):
|
||||||
"""[<channel>] [--delay] <url>
|
"""[<channel>] [--delay] <url>
|
||||||
|
@ -1198,6 +1116,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
self.stopped[msg.args[0]] = False
|
self.stopped[msg.args[0]] = False
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
|
@ -1214,8 +1135,8 @@ class ASCII(callbacks.Plugin):
|
||||||
else:
|
else:
|
||||||
irc.reply("Invalid file type.", private=False, notice=False)
|
irc.reply("Invalid file type.", private=False, notice=False)
|
||||||
return
|
return
|
||||||
file = file.content.decode()
|
file = file.content.decode().replace('\r\n','\n')
|
||||||
for line in file.splitlines():
|
for line in file.split('\n'):
|
||||||
if line.strip() and not self.stopped[msg.args[0]]:
|
if line.strip() and not self.stopped[msg.args[0]]:
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
irc.reply(line, prefixNick = False, noLengthCheck=True, private=False, notice=False, to=channel)
|
irc.reply(line, prefixNick = False, noLengthCheck=True, private=False, notice=False, to=channel)
|
||||||
|
@ -1227,6 +1148,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
opts = ''
|
opts = ''
|
||||||
if 'l' in optlist:
|
if 'l' in optlist:
|
||||||
|
@ -1238,7 +1162,7 @@ class ASCII(callbacks.Plugin):
|
||||||
if 'n' in optlist:
|
if 'n' in optlist:
|
||||||
opts += '-n '.format(n)
|
opts += '-n '.format(n)
|
||||||
if 'p' in optlist:
|
if 'p' in optlist:
|
||||||
opts += '-p '.format(p)
|
opts += '-p '
|
||||||
if 't' in optlist:
|
if 't' in optlist:
|
||||||
t = optlist.get('t')
|
t = optlist.get('t')
|
||||||
opts += '-t {0} '.format(t)
|
opts += '-t {0} '.format(t)
|
||||||
|
@ -1260,7 +1184,7 @@ class ASCII(callbacks.Plugin):
|
||||||
filepath = "{0}/tmp".format(path)
|
filepath = "{0}/tmp".format(path)
|
||||||
filename = "{0}/{1}".format(filepath, url.split('/')[-1])
|
filename = "{0}/{1}".format(filepath, url.split('/')[-1])
|
||||||
r = requests.get(url, headers=header)
|
r = requests.get(url, headers=header)
|
||||||
open(filename, 'wb').write(r.content)
|
open(filename, 'wb').write(r.content.replace(b';5;', b';'))
|
||||||
try:
|
try:
|
||||||
output = pexpect.run('a2m {0} {1}'.format(opts.strip(), str(filename)))
|
output = pexpect.run('a2m {0} {1}'.format(opts.strip(), str(filename)))
|
||||||
try:
|
try:
|
||||||
|
@ -1278,16 +1202,21 @@ class ASCII(callbacks.Plugin):
|
||||||
return
|
return
|
||||||
paste = ""
|
paste = ""
|
||||||
self.stopped[msg.args[0]] = False
|
self.stopped[msg.args[0]] = False
|
||||||
|
output = re.sub('(\x03(\d+).*)\x03,', '\g<1>\x03\g<2>,', output.decode())
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
line = line.decode()
|
|
||||||
if self.registryValue('pasteEnable', msg.args[0]):
|
if self.registryValue('pasteEnable', msg.args[0]):
|
||||||
paste += line + "\n"
|
paste += line + "\n"
|
||||||
if line.strip() and not self.stopped[msg.args[0]]:
|
if line.strip() and not self.stopped[msg.args[0]]:
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
irc.reply(line, prefixNick = False, noLengthCheck=True, private=False, notice=False, to=channel)
|
irc.reply(line, prefixNick = False, noLengthCheck=True, private=False, notice=False, to=channel)
|
||||||
|
elif not line.strip() and not self.stopped[msg.args[0]]:
|
||||||
|
time.sleep(delay)
|
||||||
|
irc.reply('\xa0', prefixNick = False, noLengthCheck=True, private=False, notice=False, to=channel)
|
||||||
|
else:
|
||||||
|
return
|
||||||
if self.registryValue('pasteEnable', msg.args[0]):
|
if self.registryValue('pasteEnable', msg.args[0]):
|
||||||
irc.reply(self.doPaste(url, paste), private=False, notice=False, to=channel)
|
irc.reply(self.doPaste(url, paste), private=False, notice=False, to=channel)
|
||||||
a2m = wrap(a2m, [optional('channel'), getopts({'l':'int', 'r':'int', 't':'int', 'w':'int', 'delay':'float'}), ('text')])
|
a2m = wrap(a2m, [optional('channel'), getopts({'l':'int', 'r':'int', 't':'int', 'w':'int', 'p':'', 'delay':'float'}), ('text')])
|
||||||
|
|
||||||
def p2u(self, irc, msg, args, channel, optlist, url):
|
def p2u(self, irc, msg, args, channel, optlist, url):
|
||||||
"""[<channel>] [--b] [--f] [--p] [--s] [--t] [--w] [--delay] <url>
|
"""[<channel>] [--b] [--f] [--p] [--s] [--t] [--w] [--delay] <url>
|
||||||
|
@ -1295,6 +1224,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
opts = ''
|
opts = ''
|
||||||
if 'b' in optlist:
|
if 'b' in optlist:
|
||||||
|
@ -1378,6 +1310,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
opts = ''
|
opts = ''
|
||||||
if 'f' in optlist:
|
if 'f' in optlist:
|
||||||
|
@ -1433,6 +1368,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
opts = ''
|
opts = ''
|
||||||
if 'f' in optlist:
|
if 'f' in optlist:
|
||||||
|
@ -1521,6 +1459,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
|
@ -1540,7 +1481,6 @@ class ASCII(callbacks.Plugin):
|
||||||
speed = 'fast'
|
speed = 'fast'
|
||||||
file = requests.get("http://wttr.in/{0}".format(location))
|
file = requests.get("http://wttr.in/{0}".format(location))
|
||||||
output = file.content.decode()
|
output = file.content.decode()
|
||||||
self.matches = {}
|
|
||||||
output = self.ansi2irc(output)
|
output = self.ansi2irc(output)
|
||||||
output = re.sub('⚡', '☇ ', output)
|
output = re.sub('⚡', '☇ ', output)
|
||||||
output = re.sub('‘‘', '‘ ', output)
|
output = re.sub('‘‘', '‘ ', output)
|
||||||
|
@ -1571,6 +1511,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
|
@ -1594,7 +1537,6 @@ class ASCII(callbacks.Plugin):
|
||||||
sub = 'usd'
|
sub = 'usd'
|
||||||
if not coin:
|
if not coin:
|
||||||
coin = ''
|
coin = ''
|
||||||
self.matches= {}
|
|
||||||
file = requests.get("http://{0}.rate.sx/{1}".format(sub, coin))
|
file = requests.get("http://{0}.rate.sx/{1}".format(sub, coin))
|
||||||
output = file.content.decode()
|
output = file.content.decode()
|
||||||
output = self.ansi2irc(output)
|
output = self.ansi2irc(output)
|
||||||
|
@ -1623,6 +1565,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
|
@ -1654,6 +1599,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
|
@ -1678,6 +1626,9 @@ class ASCII(callbacks.Plugin):
|
||||||
"""
|
"""
|
||||||
if not channel:
|
if not channel:
|
||||||
channel = msg.args[0]
|
channel = msg.args[0]
|
||||||
|
if channel != msg.args[0] and not ircdb.checkCapability(msg.prefix, 'admin'):
|
||||||
|
irc.errorNoCapability('admin')
|
||||||
|
return
|
||||||
optlist = dict(optlist)
|
optlist = dict(optlist)
|
||||||
if 'delay' in optlist:
|
if 'delay' in optlist:
|
||||||
delay = optlist.get('delay')
|
delay = optlist.get('delay')
|
||||||
|
|
Loading…
Reference in New Issue