热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Github恶搞之自定义你的contribution图表

在正式写程序之前让我先来看看效果:对了,这个程序的效果就是生成一个具有你想要的“contributionsinthelastyear”图表的html页面。当然,html文件,而不是你在Gi

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

对了,这个程序的效果就是生成一个具有你想要的“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 wordMap = new HashMap();
    private static int[][] picNumber = new int[1000][30];
    
    
    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("usage :  ");
            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 ) {
                    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 allWords = new ArrayList();
        int i;
        for (i = 0; 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 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 );
        // 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 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();
            for (int j = 0; j ) 
                for (int i = 0; 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 getWordsList() { return wordsList; }
    }
}

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

I Love You
Fxxk You

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


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
author-avatar
Jason
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有