[
  {
    "path": "README.md",
    "content": "# API\n在日常、项目或比赛过程中总结出来的小工具，方便今后。\n"
  },
  {
    "path": "UCAS-Selector/CDSelector.py",
    "content": "#coding = utf8\n# =====================================================\n#   Copyright (C) 2017 All rights reserved.\n#   \n#   filename : CDSelector.py\n#   author   : okcd00 / okcd00@qq.com\n#   revised  : zyy\n#   refer    : 617532750@qq.com\n#   date     : 2017-09-12\n#   desc     : UCAS Course_Selection Program\n# =====================================================\n\nimport os\nimport sys\nimport time\nimport requests\nfrom bs4 import BeautifulSoup\nfrom configparser import ConfigParser\n\nclass UCASEvaluate:\n    def __init__(self):\n        self.__readCoursesId('./courseid')\n\n        cf = ConfigParser()\n        cf.read('config')\n        \n        self.username = cf.get('info', 'username')\n        self.password = cf.get('info', 'password')\n        self.runtime = cf.getint('info', 'runtime')\n        self.debug = cf.getboolean('action', 'debug')\n        self.enroll = cf.getboolean('action', 'enroll')\n        self.evaluate = cf.getboolean('action', 'evaluate')\n        self.select_bat = cf.getboolean('action', 'select_bat')\n\n        self.loginPage = 'http://sep.ucas.ac.cn'\n        self.loginUrl = self.loginPage + '/slogin'\n        self.courseSystem = self.loginPage + '/portal/site/226/821'\n        self.courseBase = 'http://jwxk.ucas.ac.cn'\n        self.courseIdentify = self.courseBase + '/login?Identity='\n        self.courseSelected = self.courseBase + '/courseManage/selectedCourse'\n        self.courseSelectionBase = self.courseBase + '/courseManage/main'\n        self.courseCategory = self.courseBase + '/courseManage/selectCourse?s='\n        self.courseSave = self.courseBase + '/courseManage/saveCourse?s='\n\n        self.studentCourseEvaluateUrl = 'http://jwjz.ucas.ac.cn/Student/DeskTopModules/'\n        self.selectCourseUrl = 'http://jwjz.ucas.ac.cn/Student/DesktopModules/Course/SelectCourse.aspx'\n\n        self.enrollCount = {}\n        self.headers = {\n            'Host': 'sep.ucas.ac.cn',\n            'Connection': 'keep-alive',\n            'Pragma': 'no-cache',\n            'Cache-Control': 'no-cache',\n            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',\n            'Upgrade-Insecure-Requests': '1',\n            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36',\n            'Accept-Encoding': 'gzip, deflate, sdch',\n            'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',\n        }\n\n        self.s = requests.Session()\n        loginPage = self.s.get(self.loginPage, headers=self.headers)\n        self.cookies = loginPage.cookies\n\n    def login(self):\n        postdata = {\n            'userName': self.username,\n            'pwd': self.password,\n            'sb': 'sb'\n        }\n        self.s.post(self.loginUrl, data=postdata, headers=self.headers)\n        if 'sepuser' in self.s.cookies.get_dict(): return True\n        return False\n    \n    def getMessage(self, restext):\n        css_soup = BeautifulSoup(restext, 'html.parser')\n        text = css_soup.select('#main-content > div > div.m-cbox.m-lgray > div.mc-body > div')[0].text\n        return \"\".join(line.strip() for line in text.split('\\n'))\n    \n    def __readCoursesId(self, filename):\n        coursesFile = open(filename, 'r',encoding='UTF-8')\n        self.coursesId = {}\n        self.collegeName = {}\n        for line in coursesFile.readlines():\n            print(line)\n            line = line.strip().split(' ')\n            courseId = line[0]\n            self.collegeName[courseId] = line[1]\n            isDegree = False\n            if len(line) == 3 and line[2] == 'on':\n                isDegree = True\n            self.coursesId[courseId] = isDegree\n\n    def enrollCourses(self):\n        response = self.s.get(self.courseSystem, headers=self.headers)\n        soup = BeautifulSoup(response.text, 'html.parser')\n        try:\n            identity = str(soup).split('Identity=')[1].split('\"'[0])[0]\n            coursePage = self.courseIdentify + identity\n            response = self.s.get(coursePage)\n            response = self.s.get(self.courseSelected)\n                \n            idx, lastMsg = 0, \"\"\n            while True:\n                msg = \"\"\n                if self.select_bat: \n                    result, msg = self.__enrollCourses(self.coursesId)\n                    if result: \n                        self.coursesId.clear()\n                else:\n                    for eachCourse in self.coursesId:\n                        if eachCourse!='' and eachCourse in response.text:\n                            print(\"course \" +  eachCourse + \" has finished selected!\")\n                            continue\n                        if (eachCourse in self.enrollCount and\n                                self.enrollCount[eachCourse] == 0):\n                            continue\n                        self.enrollCount[eachCourse] = 1\n                        result, msg = self.__enrollCourse(eachCourse, self.coursesId[eachCourse])\n                        if result:\n                            self.enrollCount[eachCourse] = 0\n\n                for enroll in self.enrollCount:\n                    if self.enrollCount[enroll] == 0:\n                        self.coursesId.pop(enroll)\n                self.enrollCount.clear()\n                if not self.coursesId: return 'INVALID COURSES_ID'\n                idx += 1\n                time.sleep(self.runtime)\n                showText = \"\\r> \" + \"%s <%d> %s\" % (\n                        msg, idx,\n                        time.asctime( time.localtime(time.time()) )\n                    )\n                lastMsg = msg\n                sys.stdout.write(showText)\n                sys.stdout.flush()\n        except KeyboardInterrupt:\n            print(\"\\nKeyboardInterrupt Detected, bye!\")\n            return \"STOP\"\n        except Exception as exception:\n            return \"Course_Selection_Port is not open, waiting...\"\n             \n\n    def __enrollCourse(self, courseId, isDegree):\n        response = self.s.get(self.courseSelectionBase)\n        if self.debug:\n            with open('./check.html', 'wb+') as f:\n                f.write(response.text.encode('utf-8'))\n        soup = BeautifulSoup(response.text, 'html.parser')\n        categories = dict([(label.contents[0][:2], label['for'][3:])\n                          for label in soup.find_all('label')[2:]])\n        categoryId = categories[self.collegeName[courseId]]\n        print(categoryId)\n        identity = soup.form['action'].split('=')[1]\n\n        postdata = {\n            'deptIds': categoryId,\n            'sb': 0\n        }\n        categoryUrl = self.courseCategory + identity\n        response = self.s.post(categoryUrl, data=postdata)\n        if self.debug:\n            print (\"Now Posting, save snapshot in check2.html.\")\n            with open('./check2.html', 'wb+') as f:\n                f.write(response.text.encode('utf-8'))\n        soup = BeautifulSoup(response.text, 'html.parser')\n        courseTable = soup.body.form.table\n        if courseTable:\n            courseTable = courseTable.find_all('tr')[1:]\n        else: return False, \"Course Selection is unreachable or not started.\"\n        courseDict = dict([(c.span.contents[0], c.a['href'].split('/')[3])\n                           for c in courseTable])\n\n\n        if courseId in courseDict:\n            postdata = {\n                'deptIds': categoryId,\n                'sids': courseDict[courseId]\n            }\n\n            if isDegree:\n                postdata['did_' + courseDict[courseId]] = courseDict[courseId]\n\n            courseSaveUrl = self.courseSave + identity\n            response = self.s.post(courseSaveUrl, data=postdata)\n            \n            print (\"Now Checking, save snapshot in result.html.\")\n            with open('result.html','wb+') as f:\n                f.write(response.text.encode('utf-8'))\n            if 'class=\"error' not in response.text:\n                return True, '[Success] ' + courseId\n            else: return False, self.getMessage(response.text).strip()\n        else:\n            return False, \"No such course\"\n\n    def __enrollCourses(self, courseIds):  # For English\n        response = self.s.get(self.courseSelectionBase)\n        if self.debug: \n            with open('./check.html', 'wb+') as f:\n                f.write(response.text.encode('utf-8'))\n\n        soup = BeautifulSoup(response.text, 'html.parser')\n        categories = dict([(label.contents[0][:2], label['for'][3:])\n                          for label in soup.find_all('label')[2:]])\n        identity = soup.form['action'].split('=')[1]\n        \n        categoryIds = []\n        for courseId in courseIds:\n            categoryIds.append(categories[courseId[:2]])\n        \n        postdata = {\n            'deptIds': categoryIds,\n            'sb': 0\n        }\n        \n        categoryUrl = self.courseCategory + identity\n        response = self.s.post(categoryUrl, data=postdata)\n        \n        if self.debug: \n            print (\"Now Posting, save snapshot in check2.html.\")\n            with open('./check2.html', 'wb+') as f:\n                f.write(response.text.encode('utf-8'))\n        \n        soup = BeautifulSoup(response.text, 'html.parser')\n        courseTable = soup.body.form.table\n\n        if courseTable:\n            courseTable = courseTable.find_all('tr')[1:]\n        else: return False, \"Course Selection is unreachable or not started.\"\n        courseDict = dict([(c.span.contents[0], c.span['id'].split('_')[1])\n                           for c in courseTable])\n        postdata = {\n            'deptIds': categoryIds,\n            'sids': [courseDict[courseId] for courseId in courseIds]\n        }\n        courseSaveUrl = self.courseSave + identity\n        response = self.s.post(courseSaveUrl, data=postdata)\n        \n        print (\"Now Checking, save snapshot in result.html.\")\n        with open('result.html','wb+') as f:\n            f.write(response.text.encode('utf-8'))\n        if 'class=\"error' not in response.text:\n            return True, '[Success] ' + courseId\n        else: return False, self.getMessage(response.text).strip()\n\n            \nif __name__ == \"__main__\":\n    print(\"starting...\")\n    os.system('MODE con: COLS=128 LINES=32 & TITLE Welcome to CDSelector')\n    \n    from logo import show_logo\n    #show_logo() # delete this for faster start 23333\n    os.system('cls')\n\n    os.system(\"color 0A\")\n    os.system('MODE con: COLS=80 LINES=10 & TITLE CD_Course_Selecting is working')\n    \n    while True:\n        try:\n            ucasEvaluate = UCASEvaluate()\n            break\n        except Exception as e:\n            print(e)\n            ucasEvaluate = UCASEvaluate()\n\n    if ucasEvaluate.debug:\n        print (\"Debug Mode: %s\" % str(ucasEvaluate.debug) )\n        print (\"In debug mode, you can check snapshot with html files.\")\n        print (\"By the way, Ctrl+C to stop.\")\n    \n    if not ucasEvaluate.login():\n        print('Login error. Please check your username and password.')\n        exit()\n    print('Login success: ' + ucasEvaluate.username)\n    \n    print('Enrolling starts')\n    while ucasEvaluate.enroll:\n        status = ucasEvaluate.enrollCourses()\n        if status == 'STOP':\n            break\n        else: \n            status += time.asctime( time.localtime(time.time()) )\n            sys.stdout.write(\"%s\\r\" % status)\n    print('Enrolling finished')\n"
  },
  {
    "path": "UCAS-Selector/README.md",
    "content": "# CDSelector\nUCAS Course Selector\n\n# Usage\n+ Modify File `config`\n    + username = you@somewhere.com\n    + password = yourpassword\n+ Modify File `courseid`\n    + such as `091M7014H 物理` as 罗平老师的推荐系统课程 学院前两个字\n    + such as `09xxxxxxx 数学 on` as 某个需要被选为学位课的课程\n+ Run Script \n    + `$ python CDSelector.py`\n    + Done\n+ If not done \n    + try `$ pip install -r requirement.txt`  \n\n#  reference documentation Blog Article\nhttp://blog.csdn.net/okcd00/article/details/72827861\n"
  },
  {
    "path": "UCAS-Selector/config",
    "content": "[info]\nusername = xxxxx\npassword = xxxxx\nruntime  = 1\n\n[action]\ndebug = true\nenroll = true\nevaluate = true\nselect_bat = false\n\n"
  },
  {
    "path": "UCAS-Selector/courseid",
    "content": "14MGX017H 人文 on"
  },
  {
    "path": "UCAS-Selector/requirements.txt",
    "content": "beautifulsoup4==4.6.0\nbs4==0.0.1\nconfigparser==3.5.0\nlxml==3.7.3\nrequests==2.13.0\ntqdm==4.11.2\n"
  },
  {
    "path": "Utility/README.md",
    "content": "# API\n旨在根据现有的功能，打造一套属于自己的封装工具，方便今后。\n\n## 1. utility\n### 1.1 计算精度/召回/F1并将其存储  \n![usage](./pic/report.png)  \n这个方法有一个弊端就是最后的输出是字符串，当遇到类别特别多的情况下，终端不能很友好的显示。现在将其封装，将运行结果友好的在CSV文件中进行展示。\n```\nF1toCsv(y_true, y_pred, class_name, filepath)\n```\n`y_true`：真实标签  \n`y_pred`：预测值  \n`class_name`：类别名列表（注意类别名内部不能有空格）  \n`filepath`：存储路径  \n**Usage**\n```\ny_true = [0, 1, 2, 2, 2] \ny_pred = [0, 0, 2, 2, 1] \ntarget_names = ['class0', 'class1', 'class2'] \n\nF1toCsv(y_true, y_pred, target_names, \"result.csv\")\n```\n**结果**  \n![result](./pic/res1.png)  \n"
  },
  {
    "path": "Utility/utility.py",
    "content": "from sklearn.metrics import classification_report\nimport pandas as pd\nimport re\n\n\n\"\"\"\n计算精确率、召回率和F1值，并将其起存储在文件中\n\"\"\"\ndef F1toCsv(y_true, y_pred, class_name, filepath):\n    string = classification_report(y_true, y_pred, target_names=class_name)\n    p = re.compile(r'\\n+')\n    string = p.split(string)[:-1]\n    data = list(map(lambda x : re.sub(r\"\\s{2,}\", \"  \", x).strip().split(\"  \"), string))\n    data[0].insert(0,\" \")\n    columns, data = data[0], data[1:]\n    df = pd.DataFrame(columns=columns,data = index)\n    df.to_csv(filepath,index=False)"
  }
]