Index: trunk/tools/code-utils/amalgamer.php |
— | — | @@ -0,0 +1,196 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Basic class allowing to fetch codereview revisions metadata. |
| 6 | + */ |
| 7 | +class RevFetcher { |
| 8 | + /** How many revisions metadata we can fetch through the API |
| 9 | + * NOT IMPLEMENTED YET!!! |
| 10 | + */ |
| 11 | + const FETCH_LIMIT=50; |
| 12 | + /** Forged URL pointing to the API with correct parameters */ |
| 13 | + private $apiurl = null; |
| 14 | + /** Local rev cache object */ |
| 15 | + private $rev_cache; |
| 16 | + |
| 17 | + # Settings overridable on construction: |
| 18 | + |
| 19 | + // Path to MediaWiki API we will fetch revision from |
| 20 | + private $url = 'http://www.mediawiki.org/w/api.php' ; |
| 21 | + |
| 22 | + // A MediaWiki CodeReview repository |
| 23 | + private $repo = 'MediaWiki'; |
| 24 | + |
| 25 | + |
| 26 | + /** |
| 27 | + * On construction, you can override project URL (api.php) and code |
| 28 | + * repository. |
| 29 | + * |
| 30 | + * Example: |
| 31 | + * $rv = new RevFetcher( array( |
| 32 | + * 'url' => 'http://www.mediawiki.org/w/api.php', |
| 33 | + * 'repo' => 'mediawiki', |
| 34 | + * ) ); |
| 35 | + */ |
| 36 | + public function __construct( $opts = array() ) |
| 37 | + { |
| 38 | + $this->rev_cache = new RevCache(); |
| 39 | + |
| 40 | + if( array_key_exists( 'url', $opts) ) { |
| 41 | + $this->url = $opts['url']; |
| 42 | + } |
| 43 | + if( array_key_exists( 'repo', $opts) ) { |
| 44 | + $this->repo = $opts['repo'] ; |
| 45 | + } |
| 46 | + |
| 47 | + $this->apiurl = $this->url |
| 48 | + . "?action=query" |
| 49 | + . "&list=coderevisions" |
| 50 | + . "&crprop=revid|status|author" |
| 51 | + . "&crrepo={$this->repo}" |
| 52 | + ; |
| 53 | + |
| 54 | + # MediaWiki API requries an user agent: |
| 55 | + ini_set( 'user_agent', 'MediaWiki Amalgamer by Hashar' ); |
| 56 | + } |
| 57 | + |
| 58 | + # FIXME slice the array according to self::FETCH_LIMIT |
| 59 | + public function getRevisions( $reqRevs ) |
| 60 | + { |
| 61 | + |
| 62 | + # Normalize to array of revisions |
| 63 | + if( is_int( $reqRevs ) ) { |
| 64 | + $reqRevs = array( $reqRevs ); |
| 65 | + } |
| 66 | + |
| 67 | + print "Requesting - " . join(' | ',$reqRevs) . "\n"; |
| 68 | + |
| 69 | + $notInCache = array_diff_key( array_values($reqRevs), $this->rev_cache->allKeys() ); |
| 70 | + print " > MISSES - " . join(' | ',$notInCache) . "\n"; |
| 71 | + |
| 72 | + $inCache = array_diff_key( array_values($reqRevs), $notInCache ); |
| 73 | + print " > HITS - " . join(' | ',$inCache) . "\n"; |
| 74 | + |
| 75 | + if( empty($notInCache) ) { |
| 76 | + print "Nothing to fetch. Used cache.\n"; |
| 77 | + $fetched = array(); |
| 78 | + } else { |
| 79 | + print "Fetching " .join(' | ',$notInCache) ."\n"; |
| 80 | + # Forge URL |
| 81 | + $url = $this->apiurl |
| 82 | + . "&crrevs=" . join('|', $notInCache ) |
| 83 | + ; |
| 84 | + $fetched = |
| 85 | + $this->reallyFetch( $url ) |
| 86 | + ->query->coderevisions ; |
| 87 | + $fetched = self::rekeyRevisions( $fetched ); |
| 88 | + print "Fetched " .join( ' | ', array_keys( $fetched ) ) . "\n"; |
| 89 | + |
| 90 | + // Add fetched revisions to the cache |
| 91 | + foreach( $fetched as $f ) { |
| 92 | + $this->rev_cache->add( $f->revid, $f ); |
| 93 | + } |
| 94 | + } |
| 95 | + |
| 96 | + // return fetched + cached |
| 97 | + return array_merge( $inCache, $fetched ); |
| 98 | + } |
| 99 | + |
| 100 | + public static function rekeyRevisions( $fetched ) |
| 101 | + { |
| 102 | + $rekeyed = array(); |
| 103 | + foreach( $fetched as $r ) { |
| 104 | + $rekeyed[$r->revid] = $r; |
| 105 | + } |
| 106 | + return $rekeyed; |
| 107 | + } |
| 108 | + |
| 109 | + /** |
| 110 | + * @param $url API url |
| 111 | + * @ return array |
| 112 | + */ |
| 113 | + private function reallyFetch( $url ) |
| 114 | + { |
| 115 | + $url .= "&format=json"; |
| 116 | + //print "Fetching: $url\n"; |
| 117 | + $data = json_decode( file_get_contents( $url ) ); |
| 118 | + return $data; |
| 119 | + } |
| 120 | +} |
| 121 | + |
| 122 | +/** dumb caching system to avoid harming remote server */ |
| 123 | +class RevCache { |
| 124 | + # Array of revisions |
| 125 | + private $cache = array(); |
| 126 | + |
| 127 | + # Enable debug messages |
| 128 | + private $enableDebug = false; |
| 129 | + |
| 130 | + /** |
| 131 | + * Option 'debug' |
| 132 | + */ |
| 133 | + function __construct( $opt = array() ) |
| 134 | + { |
| 135 | + $this->enableDebug = array_key_exists( 'debug', $opt ); |
| 136 | + } |
| 137 | + |
| 138 | + /** While debugging, dump cached keys on destruction */ |
| 139 | + function __destruct() |
| 140 | + { |
| 141 | + if( $this->enableDebug ) { |
| 142 | + print "_____________________________________________\n"; |
| 143 | + print "Dumping the revision cache before destruction\n"; |
| 144 | + print join( ' | ', $this->allKeys() )."\n"; |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + /** helper : show a debugging message */ |
| 149 | + private function debug( $msg ) |
| 150 | + { |
| 151 | + if( !$this->enableDebug ) { return; } |
| 152 | + print "cache> $msg\n"; |
| 153 | + } |
| 154 | + |
| 155 | + |
| 156 | + #### PUBLIC METHODS ########################################## |
| 157 | + |
| 158 | + public function add( $key, $data ) |
| 159 | + { |
| 160 | + $this->debug( "adding key '$key'" ); |
| 161 | + $this->cache[$key] = $data; |
| 162 | + } |
| 163 | + |
| 164 | + public function del( $key ) |
| 165 | + { |
| 166 | + $this->debug( "deleting key '$key'" ); |
| 167 | + unset( $this->cache[$key] ); |
| 168 | + } |
| 169 | + |
| 170 | + public function get( $key ) |
| 171 | + { |
| 172 | + $this->debug( "getting key '$key'" ); |
| 173 | + return $this->cache[$key]; |
| 174 | + } |
| 175 | + |
| 176 | + public function hasKey( $key ) |
| 177 | + { |
| 178 | + return array_key_exists( $key, $this->cache ); |
| 179 | + } |
| 180 | + |
| 181 | + public function allKeys() |
| 182 | + { |
| 183 | + if( !$this->cache ) { return array(); } |
| 184 | + |
| 185 | + return array_keys( $this->cache ); |
| 186 | + } |
| 187 | + |
| 188 | + |
| 189 | +} |
| 190 | + |
| 191 | + |
| 192 | +$revs = array( 92286, 92289 ); |
| 193 | +$f = new RevFetcher(); |
| 194 | +$f->getRevisions( $revs ); |
| 195 | +print "NOW FETCHING 92286, should be in cache!!!!!!!!!!!!!!!!!!!!!\n"; |
| 196 | +$f->getRevisions( 92286 ); |
| 197 | + |
Property changes on: trunk/tools/code-utils/amalgamer.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 198 | + native |