package pl.shockah.shocky;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.pircbotx.Channel;
import org.pircbotx.User;
import com.sun.net.httpserver.HttpContext;
import pl.shockah.*;
import pl.shockah.shocky.paste.*;
public class Utils {
public static final Pattern
patternURL = Pattern.compile("[a-z]+://(www\\.)?[a-z0-9]+(\\.[a-z]+)+/([^/:]+/)*([^/]*)?"),
patternNick = Pattern.compile("[a-zA-Z0-9\\Q_-\\[]{}^`|\\E]+");
private static final String
mungeOriginal = "abcdefghijklmnoprstuwxyzABCDEGHIJKLMORSTUWYZ0123456789",
mungeReplace = "äḃċđëƒġħíĵķĺṁñöρŗšţüωχÿźÅḂÇĎĒĠĦÍĴĶĹṀÖŖŠŢŮŴỲŻ0123456789";
private static final String
oddOriginal = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
oddReplace = "αвcđєfġнίנкlмиoρqяsтυvωxуzαвcđєfġнίנкlмиoρqяsтυvωxуz0123456789";
private static final String
flipOriginal = "!().12345679<>?ABCDEFGJKLMPQRTUVWY[]_abcdefghijklmnpqrtuvwy{},'\"┳",
flipReplace = "¡)(˙⇂ᄅƐㄣϛ9Ɫ6><¿∀ᗺƆᗡƎℲפᒋ丬˥WԀΌᴚ⊥∩ΛMλ][‾ɐqɔpǝɟɓɥıɾʞlɯudbɹʇnʌʍʎ}{',„┻";
public static final List<PasteService> services = new LinkedList<PasteService>();
public static final Map<String,HttpContext> urls = new HashMap<String,HttpContext>();
public static List<String> getAllUrls(String text) {
String[] spl = text.split(" ");
List<String> urls = new ArrayList<String>();
for (String s : spl) if (patternURL.matcher(s).find()) urls.add(s);
return urls;
}
public static String shortenAllUrls(String text) {
List<String> urls = getAllUrls(text);
for (String url : urls) text = text.replace(url,shortenUrl(url));
return text;
}
public static String shortenUrl(String url) {
if (WebServer.exists())
{
StringBuilder sb = new StringBuilder(WebServer.getURL());
if (url.startsWith(sb.toString()))
return url;
HttpContext context;
synchronized (urls) {
if (urls.containsKey(url))
context = urls.get(url);
else {
context = WebServer.addRedirect(url);
urls.put(url, context);
}
}
sb.append(context.getPath());
return sb.toString();
}
String login = Data.config.getString("main-bitlyuser");
String key = Data.config.getString("main-bitlyapikey");
if (login==null || key==null)
return url;
try {
HTTPQuery q = HTTPQuery.create("http://api.bitly.com/v3/shorten?"+HTTPQuery.parseArgs("format","txt","login",login,"apiKey",key,"longUrl",url));
q.connect(true,true,false);
String line = q.readWhole().trim();
q.close();
if (line.startsWith("http://")) return line;
} catch (Exception e) {e.printStackTrace();}
return url;
}
public static void initPasteServices() {
String key = null;
services.clear();
services.add(new ServicePasteKdeOrg());
key = Data.config.getString("api-pastebin.com");
if (key != null)
services.add(new ServicePastebinCom(key));
key = Data.config.getString("api-pastebin.ca");
if (key != null)
services.add(new ServicePastebinCa(key));
}
public static String paste(CharSequence data) {
if (WebServer.exists() && data.length() < 5242880)
{
File file;
try {
file = File.createTempFile("shocky_paste", ".txt");
file.deleteOnExit();
FileOutputStream os = new FileOutputStream(file);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os,Helper.utf8));
bw.append(data);
bw.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
file = null;
}
if (file != null) {
StringBuilder sb = new StringBuilder(WebServer.getURL());
HttpContext context = WebServer.addPaste(file);
sb.append(context.getPath());
return sb.toString();
}
}
String link = null;
for (PasteService service : services) {
link = service.paste(data);
if (link == null) continue;
if (link.isEmpty() || link.startsWith("http://")) break;
}
return link;
}
public static String mungeAllNicks(Channel channel, int threshold, CharSequence message, User... dontMunge) {
String temp = message.toString();
if (channel == null)
return temp;
int total = 0;
User bot = channel.getBot().getUserBot();
getUsers: for (User user : channel.getUsers()) {
for (User dont : dontMunge)
if (user.equals(dont)) continue getUsers;
if (user.equals(bot))
continue;
String nick = user.getNick();
Pattern pattern = Pattern.compile(String.format("\\b%s\\b", Pattern.quote(nick)),Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(message);
if (matcher.find()) {
message = matcher.replaceAll(Matcher.quoteReplacement(mungeNick(nick)));
total++;
}
}
if (total <= threshold)
return temp;
return message.toString();
}
public static String mungeNick(CharSequence str) {
char[] chars = new char[str.length()];
for (int i = 0; i < chars.length; ++i) {
char source = str.charAt(i);
int iof = mungeOriginal.indexOf(source);
if (iof == -1) {
chars[i] = source;
continue;
}
chars[i] = mungeReplace.charAt(iof);
}
return new String(chars);
}
private static String mutate(String original, String replacement, CharSequence str) {
char[] chars = new char[str.length()];
for (int i = 0; i < chars.length; ++i) {
char source = str.charAt(i);
int iof1 = original.indexOf(source);
int iof2 = replacement.indexOf(source);
if (iof1 == -1 && iof2 == -1) {
chars[i] = source;
continue;
}
if (iof1 != -1)
chars[i] = replacement.charAt(iof1);
else if (iof2 != -1)
chars[i] = original.charAt(iof2);
}
return new String(chars);
}
public static String flip(CharSequence str) {
return mutate(flipOriginal, flipReplace, str);
}
public static String odd(CharSequence str) {
return mutate(oddOriginal, oddReplace, str);
}
public static String timeAgo(Date date) {return timeAgo(date,new Date());}
public static String timeAgo(Date from, Date to) {
long dif = (to.getTime()-from.getTime())/1000;
String time = timeAgo(dif);
if (time!="now")
return time+" ago";
return time;
}
public static long parseInterval(CharSequence str) {
long result = 0L;
int start = 0;
for (int i = 0; i < str.length(); ++i) {
char c = str.charAt(i);
if (Character.isDigit(c))
continue;
if (i > start) {
long num = Long.parseLong(str.subSequence(start, i).toString());
switch (c) {
case 's':result+=num; break;
case 'm':result+=num*(60L); break;
case 'h':result+=num*(60L*60L); break;
case 'd':result+=num*(24L*60L*60L); break;
case 'w':result+=num*(7L*24L*60L*60L); break;
}
}
start = i + 1;
}
return result;
}
public static String timeAgo(long dif) {
if (dif == 0L)
return "now";
StringBuilder sb = new StringBuilder();
int s = (int) dif % 60;dif /= 60L;
int m = (int) dif % 60;dif /= 60L;
int h = (int) dif % 24;dif /= 24L;
int d = (int) dif % 7; dif /= 7L;
int w = (int) (dif % 52.175D);
int y = (int) (dif / 52.175D);
int a = 0;
for (int i=5;i>=0;--i) {
int v;
char c;
switch(i)
{
default:
case 0: v = s;c = 's'; break;
case 1: v = m;c = 'm'; break;
case 2: v = h;c = 'h'; break;
case 3: v = d;c = 'd'; break;
case 4: v = w;c = 'w'; break;
case 5: v = y;c = 'y'; break;
}
if (a > 0)
sb.append(' ');
a |= v;
if (a > 0)
sb.append(v).append(c);
}
return sb.toString();
}
public static String timeAgo(String pt) {
if (!pt.startsWith("PT"))
return null;
int i = 2;
int num = 0;
long time = 0;
while (i < pt.length()) {
char c = pt.charAt(i++);
if (Character.isDigit(c)) {
num *= 10;
num += Character.digit(c, 10);
} else {
switch (c) {
case 'D': time += num * (60 * 60 * 24); break;
case 'H': time += num * (60 * 60); break;
case 'M': time += num * 60; break;
case 'S': time += num; break;
}
num = 0;
}
}
return timeAgo(time);
}
public static <T> T rndCollection(Collection<T> c, Random rnd) {
if (c == null || rnd == null || c.size() == 0)
return null;
int i = rnd.nextInt(c.size());
if (c instanceof RandomAccess && c instanceof List<?>)
return ((List<T>)c).get(i);
else {
for (T val : c)
if (i-- == 0)
return val;
return null;
}
}
}