diff --git a/build/service/CalendarExtractor.php b/build/service/CalendarExtractor.php new file mode 100644 index 0000000..1d58426 --- /dev/null +++ b/build/service/CalendarExtractor.php @@ -0,0 +1,269 @@ + URL of the string to extract from + * @start_d Date of the first day + * + * @return instance Instance + * + ---------------------------------------------------------*/ + public function __construct($img_url=null, $start_d=null){ + + /* [1] Check arguments + =========================================================*/ { + + /* (1) Check type */ + if( !is_string($img_url) || !is_string($start_d) ) + throw new \Exception("CalendarExtractor.__construct(, ) expected but CalendarExtractor.__construct(<".gettype($img_url).">, <".gettype($start_d).">) received"); + + /* (2) Check @img_url link availability */ + if( !($img_head=@get_headers($img_url)) ) + throw new \Exception("CalendarExtractor.__construct(, ) received but cannot reach "); + + if( !preg_match('@HTTP.+200@', $img_head[0]) ) + throw new \Exception("CalendarExtractor.__construct(, ) received but cannot reach "); + + /* (3) Check @start_d format */ + if( !preg_match("@^\d{1,2}-\d{1,2}-\d{3,}$@", $start_d) ) + throw new \Exception("CalendarExtractor.__construct(, ) received has not the correct format"); + + + } + + + /* [2] Fetch file + =========================================================*/ { + + /* (1) Try to open file with GD */ + $this->img_res = @imagecreatefrompng($img_url); + + /* (2) Manage error */ + if( !$this->img_res ) + throw new \Exception("URL is not a JPEG image, or is unreachable"); + + /* (3) Register data */ + $this->img_url = $img_url; + $this->start_d = $start_d; + + } + + } + + + + + /* (2) Extracts calendar data from image + * + * @return error FALSE on error + * + ---------------------------------------------------------*/ + public function process(){ + + /* [1] Global variables + =========================================================*/ { + + /* (1) Image size */ { + + // {1} Request for size // + $img_siz = @getimagesize($this->img_url); + + // {2} If error // + if( !$img_siz ) + throw new \Exception("Cannot get image size"); + + $img_siz = [ + 'w' => $img_siz[0], + 'h' => $img_siz[1] + ]; + + + } + + } + + + + + /* [2] Extract day limits + =========================================================*/ { + + /* (1) Will contain the column+1 w index */ + $col_ind = []; + + /* (2) Extract column indexes */ + for( $x = 0 ; $x < $img_siz['w'] ; $x++ ){ + + if( $this->getColor($x, 62) <= 10 ) + $col_ind[] = $x+1; + + } + + } + + + + /* [3] For each day -> get events + =========================================================*/ { + + /* (1) For each day */ + foreach($col_ind as $day_n=>$col_x){ + + // {1.1} Create the day in events // + $this->event[$day_n] = []; + + // {1.2} if inside a course current color, else 0 // + $cur_col = 0x0; + + + /* (2) For each y pixel -> exctract event */ + for( $y = self::$start_y ; $y < self::$stop_y ; $y++ ){ + + /* (3) Get current color + next */ + $p = $this->getColor($col_x, $y); + $p1 = $this->getColor($col_x, $y+1); + + /* (4) If on black pixel and next not white */ + if( $p == 0 && $p1 != 0xffffff ){ + + // {1} calculate time // + $time = $this->yToTime($day_n, $y); + + // {2} Store new event type (if missing) // + if( !isset($this->event_t[$p1]) ) + $this->event_t[$p1] = $this->event_t[0]++; + + // {3} Store event start // + $this->event[$this->event_t[$p1]][$time] = []; + + // {4} Seek end of event // + $y++; + while( $y < self::$stop_y && $this->getColor($col_x, $y) != 0 ) + $y++; + + // {5} If end reached // + $this->event[$this->event_t[$p1]][$time] = $this->yToTime($day_n, $y); + + } + + + + } + + } + + + } + + var_dump($this->event); + + + + die(1); + } + + + + + + /* (3) Get a pixel's color + * + * @x X coordinate + * @y Y coordinate + * + * @return color Raw color + * + ---------------------------------------------------------*/ + private function getColor($x, $y){ + return imagecolorat($this->img_res, $x, $y); + } + + + + + /* (4) Get time from a y-coordinate + * + * @day_n Day relative index + * @y y Coordinate + * + * @return time Formatted time (HH:mm) + * + ---------------------------------------------------------*/ + private function yToTime($day_n, $y){ + + /* [1] Get the date + =========================================================*/ { + + /* (1) Get the day's date */ + $day_ts = strtotime($this->start_d." + $day_n days"); + + /* (2) Format it */ + $day = date('d-m-Y', $day_ts); + + } + + + /* [2] Get the time + =========================================================*/{ + + /* (1) Get the time */ + $time = self::$start_h + (self::$stop_h-self::$start_h) * ($y-self::$start_y) / (self::$stop_y-self::$start_y); + + /* (2) Calculate hour form time */ + $hour = floor($time); + + /* (3) Calculate min from time */ + $min = round( 60 * ($time-$hour) ); + + /* (4) Round minutes to 10min */ + $min = floor($min/10)*10; + + /* (5) Format to 2-digit */ + $hour = ( $hour < 10 ) ? "0$hour" : $hour; + $min = ( $min < 10 ) ? "0$min" : $min ; + + } + + + + return "$day $hour:$min:00"; + + } + + + + + + + /* (5) Generate ICS output + * + * @return ics ICS Representation of the events + * + ---------------------------------------------------------*/ + // public function toIcs(); + + + } \ No newline at end of file diff --git a/build/service/Config.php b/build/service/Config.php new file mode 100644 index 0000000..90cb220 --- /dev/null +++ b/build/service/Config.php @@ -0,0 +1,208 @@ + '01', + 'février' => '02', + 'mars' => '03', + 'avril' => '04', + 'mai' => '05', + 'juin' => '06', + 'juillet' => '07', + 'août' => '08', + 'septembre' => '09', + 'octobre' => '10', + 'novembre' => '11', + 'décembre' => '12' + ]; + } + + + + + /* (1) Constructs a filled config object + * + * @d_list List of the diplomes ( ID => name ) + * @p_list List of the periods ( ID => first day's date ) + * + * @return this New instance + * + ---------------------------------------------------------*/ + private function __construct($d_list=null, $p_list=null){ + /* [1] Check arguments (type: array) + =========================================================*/ + if( !is_array($d_list) || !is_array($p_list) ) + throw new \Exception("Config.__construct(, , <".gettype($d_list).">) received"); + + + /* [2] Basic setter + =========================================================*/ + /* (1) Set the diplomes' list */ + $this->diplomes = $d_list; + + /* (2) Set the periods' list */ + $this->periods = $p_list; + + } + + + + /* (2) Loads the configuration from URL + * + * @d_script URL of the script containing the diplomes list + * @p_script URL of the script containing the periods list + * + * @return instance The created instance + * NULL on error + * + ---------------------------------------------------------*/ + public static function load($d_script=null, $p_script=null){ + + /* [1] Check arguments (type + validity) + =========================================================*/ { + + /* (1) Check arguments' types (string, string) */ + if( !is_string($d_script) || !is_string($p_script) ) + throw new \Exception("Config::load(, , <".gettype($d_script).">) received"); + + /* (2) Check @d_script URL validity */ + if( !($d_h=@get_headers($d_script)) ) + throw new \Exception("Config::load(<1>, <2>) received but cannot reach <1>"); + + /* (3) Check @p_script URL validity */ + if( !($p_h=@get_headers($p_script)) ) + throw new \Exception("Config::load(<1>, <2>) received but cannot reach <1>"); + + /* (4) Check image exists @dscript */ + if( !preg_match('@HTTP.+200@', $d_h[0]) ) + throw new \Exception("Config::load(<1>, <2>) received but cannot reach <1>"); + + /* (5) Check image exists @dscript */ + if( !preg_match('@HTTP.+200@', $p_h[0]) ) + throw new \Exception("Config::load(<1>, <2>) received but cannot reach <1>"); + + } + + + /* [2] Get file cursors + =========================================================*/ { + + /* (1) Try to get file cursors */ + try{ + $d_cur = new \SplFileObject($d_script, "r"); + $p_cur = new \SplFileObject($p_script, "r"); + + /* (2) Raise on failure */ + }catch(\Exception $e){ + throw new \Exception("Config::load(<1>, <2>) cannot get a cursor on a one of both files"); + } + + } + + + /* [3] Filter and register content + =========================================================*/{ + + /* (1) Manage diplomes + ---------------------------------------------------------*/ { + + /* (1) Initialize diplomes' list */ + $d_list = []; + + /* (2) Fetch each line and extract data */ + while( !$d_cur->eof() ){ + + // {1} If does not match -> go to next line // + if( !preg_match('@"grDiplome","(?:<)?(.+)(?:>)?","T(.+)"@i', $d_cur->fgets(), $m) ) + continue; + + // {2} Register into diplome list // + $d_list[ "T${m[2]}" ] = html_entity_decode($m[1]); + + } + + /* (2) Close file cursor */ + $d_cur = null; + + } + + /* (2) Manage periods + ---------------------------------------------------------*/{ + + /* (1) Initialize periods' list */ + $p_list = []; + + /* (2) Fetch each line and extract data */ + while( !$p_cur->eof() ){ + + // {1} If does not match -> go to next line // + if( !preg_match('@"T\d+","du \d+ au (\d+) ([a-z]+) (\d+)","T\d+S(.+)"@i', $p_cur->fgets(), $m) ) + continue; + + // {2} Get numeric month number // + $month = self::monthAsso()[ $m[2] ]; + + // {3} Get monday date // + $mon = date( 'd-m-Y', strtotime("${m[1]}-$month-${m[3]} - 5 days") ); + + // {4} Register into the list // + $p_list[ "S${m[4]}" ] = $mon; + + } + + /* (2) Close file cursor */ + $p_cur = null; + + } + + } + + + + + /* [4] Return the instance + =========================================================*/ + return new Config($d_list, $p_list); + + } + + + + + /* (3) Getter diplomes + * + * @return diplomes Diplome list + * + ---------------------------------------------------------*/ + public function getDiplomes(){ + return $this->diplomes; + } + + + + + /* (4) Getter periods + * + * @return periods Period list + * + ---------------------------------------------------------*/ + public function getPeriods(){ + return $this->periods; + } + + + + + + } \ No newline at end of file diff --git a/build/service/Updater.php b/build/service/Updater.php new file mode 100644 index 0000000..cdd26e8 --- /dev/null +++ b/build/service/Updater.php @@ -0,0 +1,65 @@ + New Updater + * + ---------------------------------------------------------*/ + public function __construct(){ + + /* [1] Fetch config + =========================================================*/ { + + /* (1) Try to load the configuration */ + $this->config = Config::load("http://sciences.univ-pau.fr/edt/_ressource.js", "http://sciences.univ-pau.fr/edt/_periode.js"); + + /* (2) If cannot fetch config */ + if( !($this->config instanceof Config) ) + throw new \Exception("Cannot fetch configuration"); + + } + + } + + + + /* (2) Update the ICS files + * + * @return error FALSE on error + * + ---------------------------------------------------------*/ + public function update(){ + + /* [1] Browse ech diplome + =========================================================*/ + foreach($this->config->getDiplomes() as $d_id=>$d_name){ + + /* (1) Browse each date + ---------------------------------------------------------*/ + foreach($this->config->getPeriods() as $p_id=>$p_date){ + + /* (1) Load image in the extractor */ + var_dump("http://sciences.univ-pau.fr/edt/diplomes/${d_id}${p_id}.png"); + $calext = new CalendarExtractor("http://sciences.univ-pau.fr/edt/diplomes/${d_id}${p_id}.png", $p_date); + + /* (2) Extract calendar data */ + $calext->process(); + + } + + } + } + + + + + } \ No newline at end of file diff --git a/build/service/lib/months.php b/build/service/lib/months.php deleted file mode 100644 index 9d8b758..0000000 --- a/build/service/lib/months.php +++ /dev/null @@ -1,16 +0,0 @@ - '01', - 'février' => '02', - 'mars' => '03', - 'avril' => '04', - 'mai' => '05', - 'juin' => '06', - 'juillet' => '07', - 'août' => '08', - 'septembre' => '09', - 'octobre' => '10', - 'novembre' => '11', - 'décembre' => '12' - ]; \ No newline at end of file diff --git a/build/service/lib/parse.php b/build/service/lib/parse.php deleted file mode 100644 index acb64d7..0000000 --- a/build/service/lib/parse.php +++ /dev/null @@ -1,79 +0,0 @@ - abort */ - if( $argc <= 2 ) - exit(1); - - /* (2) If @type incorrect */ - if( !in_array($argv[1], ['cursus', 'period']) ) - die(" * incorrect file type\n"); - - /* (3) Check given file */ - if( !file_exists($argv[2]) ) - die(" * file does not exist\n"); - - - - - - /* [2] Try to access file's content - =========================================================*/ - /* (1) Read file */ - $raw = file_get_contents($argv[2]); - - /* (2) Manage error */ - if( !is_string($raw) ) - die(" * Cannot read file\n"); - - /* (3) Split by lines */ - $raw = explode("\n", $raw); - - - - /* [3] Parse data - =========================================================*/ - /* (1) Prepare the output list */ - $list = []; - - /* (2) Cursur parser */ - if( $argv[1] == 'cursus' ){ - - foreach($raw as $line) - if( preg_match('@"grDiplome","(?:<)?(.+)(?:>)?","T(.+)"@i', $line, $m) ) - $list[ html_entity_decode($m[1]) ] = "T${m[2]}"; - - /* (3) Period parser */ - }else{ - - $first = null; - - foreach($raw as $line){ - - if( preg_match('@"T\d+","du \d+ au (\d+) ([a-z]+) (\d+)","T\d+S(.+)"@i', $line, $m) ){ - - /* (3.1) Translate month */ - $month = $monthList[$m[2]]; - - /* (3.2) Get date of monday */ - $list[ "S${m[4]}" ] = date('d-m-Y', strtotime("${m[1]}-$month-${m[3]} - 5 days")); - } - - } - } - - - - /* [4] Write data back - =========================================================*/ - if( !file_put_contents("$ABSROOT/../../tmp/${argv[1]}.json", json_encode($list)) ) - die(" * Cannot write parsed data back\n"); - - - exit(0); \ No newline at end of file diff --git a/build/service/lib/update.php b/build/service/lib/update.php deleted file mode 100644 index 967b7e3..0000000 --- a/build/service/lib/update.php +++ /dev/null @@ -1,92 +0,0 @@ - "$ABSROOT/../../tmp/cursus.json", - 'period' => "$ABSROOT/../../tmp/period.json", - ]; - - /* (1) cursus list */ - if( !file_exists($path['cursus']) ) - die(" * Missing tmp/cursus.json\n"); - - /* (2) period list */ - if( !file_exists($path['period']) ) - die(" * Missing tmp/period.json\n"); - - } - - - /* [2] Parse cursus list - =========================================================*/ { - /* (1) Read from file */ - $clist = file_get_contents($path['cursus']); - - /* (2) Manage error */ - if( $clist == false ) - die(" * Cannot read cursus file\n"); - - /* (3) Parse JSON */ - $clist = json_decode($clist, true); - - /* (4) Manage error */ - if( $clist == null ) - die(" * Cannot parse cursus file\n"); - - } - - - /* [3] Parse period list - =========================================================*/ { - - /* (1) Read from file */ - $plist = file_get_contents($path['period']); - - /* (2) Manage error */ - if( $plist == false ) - die(" * Cannot read period file\n"); - - /* (3) Parse JSON */ - $plist = json_decode($plist, true); - - /* (4) Manage error */ - if( $plist == null ) - die(" * Cannot parse period file\n"); - - } - - - - /* [4] Manage each cursus - =========================================================*/ { - - /* (1) For each cursus */ - foreach($clist as $cname=>$cvalue){ - - /* (1.2) Create a directory */ - if( !file_exists("$ABSROOT/../../tmp/$cvalue") ) - file_put_contents("$ABSROOT/../../tmp/$cvalue.ics", ""); - - - /* (1) Download all images - ---------------------------------------------------------*/ - foreach($plist as $pvalue=>$pdate) - "http://sciences.univ-pau.fr/edt/diplomes/${cvalue}${pvalue}.png"; // image file - - - } - - - } - - - - - diff --git a/build/service/main.sh b/build/service/main.sh deleted file mode 100644 index 1699c46..0000000 --- a/build/service/main.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# Absolute root dir -ABSROOT=$( dirname $(realpath $0) ); - - - -# [1] Download the list of Diplomes -#========================================================# -# (1) Get the diplomes list # -wget http://sciences.univ-pau.fr/edt/_ressource.js -qO $ABSROOT/../../tmp/cursus.js && echo "* downloaded successfully" || echo "* download failed" || exit 1; - -# (2) Get Period list # -wget http://sciences.univ-pau.fr/edt/_periode.js -qO $ABSROOT/../../tmp/period.js && echo "* downloaded successfully" || echo "* download failed" || exit 1; - - - - -# [2] Parse these lists -#========================================================# -# (1) Parse the diplomes list # -php $ABSROOT/lib/parse.php cursus $ABSROOT/../../tmp/cursus.js && echo "* parsed successfully" || echo "* parsing failed" || exit 1; - -# (2) Parse the period list # -php $ABSROOT/lib/parse.php period $ABSROOT/../../tmp/period.js && echo "* parsed successfully" || echo "* parsing failed" || exit 1; - - - - -# [3] Update ICS files -#========================================================# -# (1) Create ICS files # -php $ABSROOT/lib/update.php; - -# (2) Remove buffer data # -rm -r $ABSROOT/../../tmp/*.ics - - - - -# [X] Remove downloaded original files -#========================================================# -# (1) Remove cursus # -rm $ABSROOT/../../tmp/cursus.js && echo "* removed successfully" || echo "* removing failed" || exit 1; - -# (2) Remove period # -rm $ABSROOT/../../tmp/period.js && echo "* removed successfully" || echo "* removing failed" || exit 1; - diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..fa70fb0 --- /dev/null +++ b/install.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +sudo apt-get install php7.0-gd; +sudo service apache2 restart; \ No newline at end of file diff --git a/public_html/index.php b/public_html/index.php index 2559cc6..38d88f9 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -1,6 +1,13 @@ update(); + + // var_dump( imagecreatefrompng("http://sciences.univ-pau.fr/edt/diplomes/T0000000378S0000000000002.png") ); echo "bla";