在正式写程序之前让我先来看看效果:

对了,这个程序的效果就是生成一个具有你想要的“contributions in the last year”图表的html页面。
当然,html文件,而不是你在Github上面个人主页中的实际的页面。
当然,你可以通过个人努力达到效果(我之前就见过一个I 心 U,但是暂时没有找到出处),不过那需要非常努力和耐性,并且那么做的话收获更多(如果不是仅仅为了那么做而commit+push的话),所以这里介绍一个程序来实现这种方法。
接下来我将用Java来编写程序,主要分为两个步骤:

  1. 下载网页源代码
  2. 根据自己设计的字体替换网页中对应的内容

其中第二步有很多现有的工具,比如Jsoup,但是可以用正则表达式直接解决,后来我发现一个写起来比较方便的方法,因为我发现每一种颜色对应一个fill元素,所以可以直接从fill元素下手。
我把设计的字体保存在了文件picture-fonts.txt(是一个只有字符"0"和"1"的字符文件)中,并把每个字符在picture-fonts.txt中的位置保存在了position.txt中。
他们的预期效果如下:

这意味着在这里你暂时只能达到“ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”的效果。
“contributions in the last year”列表里面一共有7行53列,为了保(tou)险(lan)这里就先不去动最后一列了。所以我们有7行52列可以用,所以这个程序将会输出最多的我们想要的结果。
程序的代码就一个,内容如下:

package fungithub;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class FunGithub { private static Map<String, Word> wordMap = new HashMap<String, Word>();
private static int[][] picNumber = new int[1000][30]; public static void main(String[] args) {
if (args.length != 2) {
System.err.println("usage : <username> <words>");
System.exit(1);
}
solve(args[0], args[1]);
} public static void solve(String username, String words) {
words = words.toUpperCase();
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.dir") + "/picture-fonts.txt"), "utf-8"))
) {
int idx = 0;
String line = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.length() == 0) continue;
int len = line.length();
char[] ch = line.toCharArray();
for (int i = 0; i < len; i ++) {
char c = ch[i];
picNumber[idx][i] = (int) c - (int)'0';
}
idx ++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.dir") + "/position.txt"), "utf-8"))
) {
String line = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.length() == 0) continue;
Word temp = new Word(line);
wordMap.put(temp.getC(), temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} List<Integer> allWords = new ArrayList<Integer>();
int i;
for (i = 0; i < words.length(); i ++) {
String oneWordString = String.format("%c", words.charAt(i));
Word oneWord = wordMap.get(oneWordString);
if (oneWord == null) {
System.err.println(oneWordString + " not exists!");
continue;
}
List<Integer> tmpWordsList = oneWord.getWordsList();
if (allWords.size() + tmpWordsList.size() > 52 * 7)
break;
else {
allWords.addAll(tmpWordsList);
if (allWords.size() + 7 <= 52 * 7)
for (int j = 0; j < 7; j ++)
allWords.add(0);
}
}
System.out.println("\"" + words.substring(0, i) +"\" solved!");
int delta = 52 * 7 - allWords.size();
for (int j = 0; j < delta; j ++) allWords.add(0);
// allWords -- the list with 52 * 7 words generated. // download url content
URL url = null;
HttpURLConnection urlConnection = null;
BufferedReader reader;
String pageContent = "";
try {
url = new URL("https://github.com/" + username);
urlConnection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line;
while ((line = reader.readLine()) != null){
pageContent += line + "\n";
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} pageContent = pageContent.replaceAll("fill=\"#[0-9a-e]{6}\"", "MoON1igHt");
for (int word : allWords) {
String fillStr = null;
if (word == 1) {
fillStr = "fill=\"#1e6823\"";
} else {
double r = Math.random();
if (r <= 0.3) fillStr = "fill=\"#eeeeee\"";
else if (r <= 0.9) fillStr = "fill=\"#d6e685\"";
else if (r <= 0.96) fillStr = "fill=\"#8cc665\"";
else fillStr = "fill=\"#44a340\"";
}
pageContent = pageContent.replaceFirst("MoON1igHt", fillStr);
}
pageContent = pageContent.replaceAll("MoON1igHt", "fill=\"#eeeeee\""); // write content to output html file, here I set it to Desktop, here I am the user "Administrator" on Windows7
String outputFileName = "C:/Users/Administrator/Desktop/" + username + "-" + words + ".html";
try (
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(outputFileName), "utf-8");
) {
osw.write(pageContent);
} catch (UnsupportedEncodingException | FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} System.out.println(username + "-" + words + ".html successifully generated at desktop!");
} static class Word { private String c;
private int px;
private int py;
private int height;
private int width;
private List<Integer> wordsList; public Word(String line) {
String[] arr = line.split(",");
c = arr[0];
px = Integer.parseInt(arr[1]);
py = Integer.parseInt(arr[2]);
height = Integer.parseInt(arr[3]);
width = Integer.parseInt(arr[4]); // generate wordsList
wordsList = new ArrayList<Integer>();
for (int j = 0; j < width; j ++)
for (int i = 0; i < height; i ++)
wordsList.add(picNumber[px+i][py+j]);
} public String getC() { return c; }
public int getPx() { return px; }
public int getPy() { return py; }
public int getHeight() { return height; }
public int getWidth() { return width; }
public List<Integer> getWordsList() { return wordsList; }
}
}

另外还有2个资源文件,Github项目位置:https://github.com/moonlightpoet/FunGithub 有兴趣可以玩一下。
另外github pages上面放了两个可以看看在线效果(一个I Love you的和一个Fxxk you的):

I Love You
Fxxk You

注:今天找到了知乎上问题的出处

Github恶搞之自定义你的contribution图表的更多相关文章

  1. 4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况、存在的问题及解决的方案。(尤心心)

    4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况.存在的问题及解决的方案. (1)利用github本身的graphs可以清晰的看出小组成员在github上面的交互,可以直接 ...

  2. Github 恶搞教程(一起『玩坏』自己的 Github 吧)

    最近在伯乐在线读到一篇趣文,<如何在 Github『正确』做贡献>,里面各种能人恶搞 Github 的『Public contributions』,下面截取几个小伙伴的战绩: 顺藤摸瓜,发 ...

  3. GitHub pages+自定义域名(腾讯云域名)+cloudflare加速

    本人也是第一次走完整个流程,github pages当然一直有使用,创建也很简单,并且网上教程也比较多:然后是关于自定义域名的问题,自己以前使用过国外的免费域名,然后是直接修改就ok了,然后这次使用了 ...

  4. JHChart 1.1.0 iOS图表工具库中文ReadMe

    JHChart(最新版本1.1.0) 好吧,的确当前的github上已经存有不少的iOS图表工具库,然而,当公司的项目需要图表时,几乎没有哪个第三方能够完全满足我的项目需求.无奈之下,本人不得不花费一 ...

  5. 美丽的Java图表类库

    摘要 在使用java做后台站点的开发张,图表和报表功能都是不可或缺 的.本文推荐了8款最精彩实用的Java图表应用,大部分图表应用的功能都类似,主要在于界面的美观性和使用的灵活性上有一点高低. 正文 ...

  6. 非常有用的GitHub链接

    平常开发工作中,我经常取Github上搜索项目,Clone下来学习使用,在这个过程中,发现了好多比较好的Github地址,记录下来,分享出去. image 非常有用的GitHub链接(顺序不分先后): ...

  7. Chart 图表开源项目总结

    在Android开发中,我们不免会遇到图表展示的需求,以下是本人之前star的悬浮窗的开源项目,供大家参考: 1. WilliamChart:创建图表的Android库 2. HelloCharts: ...

  8. Github使用教程(一)------ 初识Github

    上一节我们解决了Github网站响应慢,加载不完全的情况,接下来我们就要正式开始使用Github了. :好,那我先安装Git,稍后就上传项目. :......你Github网站都看懂了? :还需要看懂 ...

  9. 2019最新Android常用开源库总结(附带github链接)

    前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 1.TextView HTextView ...

随机推荐

  1. python正则表达式里引入变量

    import re def reg_exp(senten): jiqiren = "阿童木" matchObj1 = re.search( r'(你(.*?)(男|女))|(机器( ...

  2. 【小程序】小程序开发自定义组件的步骤>>>>>>>>>小程序开发过程中报错:jsEnginScriptError

    报错:jsEnginScriptError VM6342: jsEnginScriptError Component is not found in path "component/spac ...

  3. Socket.IO学习之基础入门

    原文:http://blog.csdn.net/weichuang_1/article/details/48831957 这里贴出Socket.IO官网 一.Socket.IO的介绍 Socket.I ...

  4. VS2008 编译出错 fatal error C1859: unexpected precompiled header error, simply rerunning the compiler might fix this problem

    https://jingyan.baidu.com/article/d8072ac49ebd23ec95cefddd.html

  5. mysql数据库全备和全备还原(使用Xtrabackup)

    一.使用innobackupex创建全备 语法 innobackupex --user=DBUSER --password=DBUSERPASS /path/to/backup/dir/ innoba ...

  6. Xtrabackup简介

    Xtrabackup是由 Percona 开发的一个开源软件,可实现对 InnoDB 的数据备份,支持在线热备份(备份时不影响数据读写),特点如下: 备份过程快速.可靠: 备份过程不会打断正在执行的事 ...

  7. [dubbo] Dubbo API 笔记——配置参考

    schema 配置参考 所有配置项分为三大类 服务发现:表示该配置项用于服务的注册与发现,目的是让消费方找到提供方 服务治理:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件 性能调优:表示 ...

  8. Linux下修改Mysql的用户(root)的密码的俩种方法

     from:https://www.cnblogs.com/daizhuacai/archive/2013/01/17/2865138.html   修改的用户都以root为列.一.拥有原来的myql ...

  9. 批量备份数据库脚本(PowerShell版)

    开始 昨天备份一个数据库拿来测试,发现备份后的文件非常大.后来去检查下使用的备份脚本,原来之前的备份脚本没有压缩功能. 现把之前的备份脚本修改下,支持压缩备份,和支持仅复制备份(CopyOnly). ...

  10. 我的IT之路这样走过

    一.我的IT之路这样走过: 1.大一上学期.我们学校是用C语言做启蒙语言的:虽然我学的相当不错,但是我发现一个问题:用C语言做软件那么它的交付周期比较长. 对于我这种无产阶级来说最关键的是解眼下的粮食 ...