├── .gitignore ├── .npmrc ├── Build.php ├── LICENSE ├── README.md ├── composer.json ├── data ├── proposed-change.json ├── proposed-new.json └── types.json ├── import-scripts ├── amarillo │ └── meeting-guide.php ├── annapolis │ └── annapolis.php ├── baltimore │ ├── 12-step-meeting-list.php │ ├── meetings-api.php │ └── style.css ├── broward-county │ └── meeting-guide.php ├── calgary │ └── calgary-meeting-guide.php ├── cape-atlantic │ ├── meeting-guide.php │ └── readme.txt ├── charlotte │ └── meeting-guide.cfm ├── georgia │ └── meeting-guide.php ├── las-vegas │ └── meeting-guide.php ├── los-angeles │ └── meeting-guide.php ├── low-country │ └── meeting-guide.php ├── nashville │ └── meeting-guide.php ├── nemdaa │ └── meeting-guide.php ├── new-hampshire │ └── new-hampshire.php ├── new-mexico │ └── new-mexico.php ├── oklahoma-city │ └── oklahoma_city.php ├── orange-county │ ├── meeting-guide.aspx │ ├── meeting-guide.aspx.cs │ └── meeting-guide.php ├── ottawa │ └── meeting-guide-json.php ├── phoenix │ └── meeting-guide.php ├── pittsburgh │ └── meeting-guide.php ├── puget-sound │ └── datatojson.py ├── san-antonio │ └── meeting-guide.php ├── san-francisco │ └── san-francisco.cfm ├── santa-barbara │ └── santa-barbara.php ├── southern-illinois │ └── meetingguide.php ├── st-louis │ └── st-louis.php ├── suffolk-county │ └── meeting-guide.php ├── tecmgc │ └── tecmgc.php ├── tucson │ └── meeting-guide.php ├── tulsa │ └── tulsa.php ├── utah │ └── meeting-guide.php └── winston-salem │ └── winston-salem.php ├── jestconfig.json ├── package-lock.json ├── package.json ├── src ├── Spec.php ├── __tests__ │ └── index.spec.ts ├── index.ts ├── languages.ts ├── types.php └── types.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /lib 3 | /coverage 4 | /vendor/ 5 | composer.phar 6 | /.idea -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.com/ -------------------------------------------------------------------------------- /Build.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @since 1.0.0 12 | */ 13 | 14 | namespace Code4Recovery; 15 | 16 | class Build 17 | { 18 | /** 19 | * The path to the json file containing spec data. 20 | * @var array 21 | */ 22 | private array $tables = [ 23 | [ 24 | 'file' => './data/types.json', 25 | 'delimiterTop' => '', 26 | 'delimiterBottom' => '', 27 | ], 28 | [ 29 | 'file' => './data/proposed-new.json', 30 | 'delimiterTop' => '', 31 | 'delimiterBottom' => '', 32 | 33 | ], 34 | [ 35 | 'file' => './data/proposed-change.json', 36 | 'delimiterTop' => '', 37 | 'delimiterBottom' => '', 38 | 39 | ] 40 | ]; 41 | 42 | /** 43 | * The path to the readme.md that will be created. 44 | * @var string 45 | */ 46 | private string $readmeFile = './README.md'; 47 | 48 | /** 49 | * Languages used in the types table 50 | * @var array 51 | */ 52 | private array $languages = [ 53 | 'en' => 'English', 54 | 'es' => 'Español', 55 | 'fr' => 'Français', 56 | 'ja' => '日本語', 57 | 'nl' => 'Nederlands', 58 | 'pt' => 'Português', 59 | 'sk' => 'Slovenčina', 60 | 'sv' => 'Svenska', 61 | ]; 62 | 63 | /** 64 | * Constructor. 65 | * 66 | * @param $specFile: Path to spec json file, relative to project root. 67 | * @param $readmeFile: Path to readme file, relative to project root. 68 | */ 69 | public function __construct() 70 | { 71 | foreach ($this->tables as $table) { 72 | $this->writeReadme($table); 73 | } 74 | $this->writeTypeScript(); 75 | $this->writePHPObject(); 76 | } 77 | 78 | /** 79 | * Builds a types table. 80 | * 81 | * @return string Markdown for table 82 | */ 83 | private function createTable($table): string 84 | { 85 | return implode(PHP_EOL, [ 86 | $table['delimiterTop'], 87 | $this->createTableHeader(), 88 | $this->createTableRows($table['file']), 89 | $table['delimiterBottom'], 90 | ]); 91 | } 92 | 93 | /** 94 | * Creates the table header markup. 95 | * 96 | * @return string 97 | */ 98 | private function createTableHeader(): string 99 | { 100 | // Columns 101 | $headerColumns = array_merge(['Code'], array_values($this->languages)); 102 | 103 | // Dashes 104 | $rows = [$headerColumns, array_fill(0, count($headerColumns), '---')]; 105 | 106 | // Build final markup with line breaks 107 | return implode(PHP_EOL, array_map([$this, 'createTableRow'], $rows)); 108 | } 109 | 110 | /** 111 | * Creates a table row separated (and surrounded) by pipes. 112 | * 113 | * @param array $row 114 | * 115 | * @return string 116 | */ 117 | private function createTableRow($row): string 118 | { 119 | return implode('|', array_merge([''], $row, [''])); 120 | } 121 | 122 | /** 123 | * Gets the contents of the spec file and creates the table rows markup. 124 | * 125 | * @return string 126 | */ 127 | private function createTableRows($specFile): string 128 | { 129 | // Init empty array 130 | $specRows = []; 131 | 132 | // Get spec data & language codes 133 | $specJson = json_decode(file_get_contents($specFile), true); 134 | $languages = array_keys($this->languages); 135 | 136 | // Loop through types from spec 137 | foreach ($specJson as $key => $value) { 138 | // Begin row output. Empty the $columns array each time. 139 | $specColumns = ['`' . $key . '`']; 140 | 141 | // Loop through languages 142 | foreach ($languages as $languageKey) { 143 | 144 | // Add translation to columns 145 | $specColumns[] = array_key_exists($languageKey, $value) ? $value[$languageKey] : '-'; 146 | } 147 | 148 | // Add empty array values so our row is surrounded by pipes 149 | $specRows[] = $this->createTableRow($specColumns); 150 | } 151 | return implode(PHP_EOL, $specRows); 152 | } 153 | 154 | /** 155 | * Get the contents of the readme, replace the types table, and re-write. 156 | * 157 | * @param string $tableContent The markdown to write to the file 158 | * 159 | * @return void 160 | */ 161 | private function writeReadme(array $table): void 162 | { 163 | // Get the current readme contents 164 | $readmeContents = file_get_contents($this->readmeFile); 165 | 166 | // Get the new table content 167 | $tableContent = $this->createTable($table); 168 | 169 | // Replace existing table 170 | $result = preg_replace('#(' . preg_quote($table['delimiterTop']) . ')(.*)(' . preg_quote($table['delimiterBottom']) . ')#siU', $tableContent, $readmeContents); 171 | 172 | // Write new file 173 | $readmeHandle = fopen($this->readmeFile, "w") or die("Unable to open file!"); 174 | fwrite($readmeHandle, $result); 175 | fclose($readmeHandle); 176 | } 177 | 178 | /** 179 | * Write the typescript file 180 | * 181 | * @return void 182 | */ 183 | private function writeTypeScript(): void 184 | { 185 | file_put_contents('./src/languages.ts', 'export const languages = ' . json_encode(array_keys($this->languages)) . ' as const;'); 186 | $json = file_get_contents('./data/types.json'); 187 | file_put_contents('./src/types.ts', 'export const types = ' . $json . ';'); 188 | } 189 | 190 | private function writePHPObject(): void 191 | { 192 | // Fetch the JSON file 193 | $jsonData = file_get_contents('./data/types.json'); 194 | if ($jsonData === false) { 195 | die("Error fetching JSON file."); 196 | } 197 | 198 | // Decode JSON data 199 | $dataObject = json_decode($jsonData); 200 | if ($dataObject === null) { 201 | die("Error decoding JSON data."); 202 | } 203 | 204 | // Prepare the PHP content 205 | $phpContent = " 4 | Copyright (c) 2015 Márk Sági-Kazár 5 | Copyright (c) 2015 Graham Campbell 6 | Copyright (c) 2016 Tobias Schultze 7 | Copyright (c) 2016 George Mponos 8 | Copyright (c) 2018 Tobias Nyholm 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code4recovery/spec", 3 | "description": "The goal of the Meeting Guide API is help sync information about AA meetings. It was developed for the Meeting Guide app, but it is non-proprietary and other systems are encouraged to make use of it.", 4 | "require": { 5 | "php": ">=7.4", 6 | "ext-json": "*" 7 | }, 8 | "license": "MIT", 9 | "autoload": { 10 | "psr-4": { 11 | "Code4Recovery\\": "src" 12 | } 13 | }, 14 | "authors": [ 15 | { 16 | "name": "Code for Recovery" 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /data/proposed-change.json: -------------------------------------------------------------------------------- 1 | { 2 | "LGBTQ": { 3 | "en": "LGBTQIAA+", 4 | "es": "LGBTQIAA+", 5 | "fr": "LGBTQIAA+", 6 | "ja": "LGBTQIAA+", 7 | "nl": "LGBTQIAA+", 8 | "pt": "LGBTQIAA+", 9 | "sk": "LGBTQIAA+", 10 | "sv": "HBTQIAA+" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /data/proposed-new.json: -------------------------------------------------------------------------------- 1 | { 2 | "BV-I": { 3 | "en": "Blind / Visually Impaired", 4 | "es": "Ciego / Discapacidad Visual", 5 | "fr": "Aveugle / Malvoyant", 6 | "ja": "視覚障害者", 7 | "nl": "Blind / Visueel gehandicapt", 8 | "pt": "Cego / Deficiência Visual", 9 | "sk": "Nevidiaci / Zrakovo postihnutí", 10 | "sv": "Blind / Synskadad" 11 | }, 12 | "D-HOH": { 13 | "en": "Deaf / Hard of Hearing", 14 | "es": "Sordo / Duro de Oído", 15 | "fr": "Sourd / Malentendant", 16 | "ja": "聴覚障害者", 17 | "nl": "Doof / Hardhoren", 18 | "pt": "Surdo / Duro de Ouvido", 19 | "sk": "Nepočujúci / Nedoslýchaví", 20 | "sv": "Döv / Hörselskadad" 21 | }, 22 | "LO-I": { 23 | "en": "Loners / Isolationists", 24 | "es": "Solitarios / Aislacionistas", 25 | "fr": "Solitaires / Isolationnistes", 26 | "ja": "孤独 / 孤立主義者", 27 | "nl": "Eenlingen / Isolationisten", 28 | "pt": "Solitários / Isolacionistas", 29 | "sk": "Samotári / Izolacionisti", 30 | "sv": "Ensamvargar / Isolationister" 31 | }, 32 | "QSL": { 33 | "en": "Quebec Sign Language", 34 | "es": "Lengua de Señas de Quebec", 35 | "fr": "Langue des Signes Québécoise", 36 | "ja": "ケベック手話", 37 | "nl": "Quebec -gebarentaal", 38 | "pt": "Língua Gesual Quebec", 39 | "sk": "Quebecký posunkový jazyk", 40 | "sv": "Quebecskt Teckenspråk" 41 | }, 42 | "RSL": { 43 | "en": "Russian Sign Language", 44 | "es": "Lengua de Señas Rusa", 45 | "fr": "Langue des Signes Russe", 46 | "ja": "ロシア手話", 47 | "nl": "Russische gebarentaal", 48 | "pt": "Língua Gestual Russa", 49 | "sk": "Ruský posunkový jazyk", 50 | "sv": "Ryskt Teckenspråk" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /data/types.json: -------------------------------------------------------------------------------- 1 | { 2 | "11": { 3 | "en": "11th Step Meditation", 4 | "es": "Meditación del Paso 11", 5 | "fr": "Méditation sur la 11e Étape", 6 | "ja": "ステップ11 黙想", 7 | "nl": "Stap 11 meditatie", 8 | "pt": "Meditação do 11º Passo", 9 | "sk": "Meditácia 11. kroku", 10 | "sv": "11th Stegs Meditation" 11 | }, 12 | "12x12": { 13 | "en": "12 Steps & 12 Traditions", 14 | "es": "12 Pasos y 12 Tradiciones", 15 | "fr": "12 Étapes et 12 Traditions", 16 | "ja": "12のステップと12の伝統", 17 | "nl": "12 Stappen en 12 Tradities", 18 | "pt": "12 Passos e 12 Tradições", 19 | "sk": "12 Krokov & 12 Tradícií", 20 | "sv": "12 Steg & 12 Traditioner" 21 | }, 22 | "A": { 23 | "en": "Secular", 24 | "es": "Secular", 25 | "fr": "Séculier", 26 | "ja": "無宗教", 27 | "nl": "Seculier", 28 | "pt": "Secular", 29 | "sk": "Svetské", 30 | "sv": "Sekulärt" 31 | }, 32 | "ABSI": { 33 | "en": "As Bill Sees It", 34 | "es": "Como lo ve Bill", 35 | "fr": "Réflexions de Bill", 36 | "ja": "ビルはこう思う", 37 | "nl": "Zoals Bill het ziet", 38 | "pt": "Na opinião de Bill", 39 | "sk": "Ako to vidí Bill", 40 | "sv": "Som Bill Ser Det" 41 | }, 42 | "AF": { 43 | "en": "Afrikaans", 44 | "es": "Afrikáans", 45 | "fr": "Afrikaans", 46 | "ja": "アフリカーンス語", 47 | "nl": "Afrikaans", 48 | "pt": "Afrikaans", 49 | "sk": "Afrikánčina", 50 | "sv": "Afrikaans" 51 | }, 52 | "AL": { 53 | "en": "Concurrent with Alateen", 54 | "es": "Concurrente con Alateen", 55 | "fr": "En même temps qu’Alateen", 56 | "ja": "アラティーンと同時進行", 57 | "nl": "Gelijktijdig met Alateen", 58 | "pt": "Em simultâneo com Alateen", 59 | "sk": "Súbežne s Alateen", 60 | "sv": "Tillsammans med Alateen" 61 | }, 62 | "AL-AN": { 63 | "en": "Concurrent with Al-Anon", 64 | "es": "Concurrente con Al-Anon", 65 | "fr": "En même temps qu’Al-Anon", 66 | "ja": "アラノンと同時進行", 67 | "nl": "Gelijktijdig met Al-Anon", 68 | "pt": "Em simultâneo com Al-Anon", 69 | "sk": "Súbežne s Al-Anon", 70 | "sv": "Tillsammans med Al-Anon" 71 | }, 72 | "AM": { 73 | "en": "Amharic", 74 | "es": "Amárico", 75 | "fr": "Amharique", 76 | "ja": "アムハラ語", 77 | "nl": "Amhaars", 78 | "pt": "Amárico", 79 | "sk": "Amharčina", 80 | "sv": "Amhariska" 81 | }, 82 | "AR": { 83 | "en": "Arabic", 84 | "es": "Árabe", 85 | "fr": "Arabe", 86 | "ja": "アラビア語", 87 | "nl": "Arabisch", 88 | "pt": "Árabe", 89 | "sk": "Arabské", 90 | "sv": "Arabiska" 91 | }, 92 | "ASL": { 93 | "en": "American Sign Language", 94 | "es": "Lenguaje por señas", 95 | "fr": "Langage des Signes", 96 | "ja": "アメリカ手話", 97 | "nl": "Amerikaanse gebaren taal", 98 | "pt": "Língua Gestual Americana", 99 | "sk": "Americký posunkový jazyk", 100 | "sv": "Amerikanskt teckenspråk" 101 | }, 102 | "B": { 103 | "en": "Big Book", 104 | "es": "Libro Grande", 105 | "fr": "Gros Livre", 106 | "ja": "ビッグブック", 107 | "nl": "Big Book", 108 | "pt": "Livro Azul", 109 | "sk": "Veľká Kniha", 110 | "sv": "Stora Boken" 111 | }, 112 | "BA": { 113 | "en": "Babysitting Available", 114 | "es": "Guardería disponible", 115 | "fr": "Garderie d’enfants disponible", 116 | "ja": "ベビーシッターあり", 117 | "nl": "Kinderopvang aanwezig", 118 | "pt": "Babysitting disponível", 119 | "sk": "Dostupné opatrovanie detí", 120 | "sv": "Barnvakt Finns" 121 | }, 122 | "BE": { 123 | "en": "Newcomer", 124 | "es": "Principiantes", 125 | "fr": "Nouveau/nouvelle", 126 | "ja": "ビギナーズ", 127 | "nl": "Nieuwkomer", 128 | "pt": "Recém-chegados", 129 | "sk": "Nováčikovia", 130 | "sv": "Nykomling" 131 | }, 132 | "BG": { 133 | "en": "Bulgarian", 134 | "es": "Búlgaro", 135 | "fr": "Bulgare", 136 | "ja": "ブルガリア語", 137 | "nl": "Bulgaars", 138 | "pt": "Búlgaro", 139 | "sk": "Bulharské", 140 | "sv": "Bulgariska" 141 | }, 142 | "BI": { 143 | "en": "Bisexual", 144 | "es": "Bisexual", 145 | "fr": "Bisexuel", 146 | "ja": "バイセクシャル", 147 | "nl": "Biseksueel", 148 | "pt": "Bisexual", 149 | "sk": "Bisexuálne", 150 | "sv": "Bisexuellt" 151 | }, 152 | "BRK": { 153 | "en": "Breakfast", 154 | "es": "Desayuno", 155 | "fr": "Petit déjeuner", 156 | "ja": "朝食", 157 | "nl": "Ontbijt", 158 | "pt": "Pequeno-Almoço", 159 | "sk": "Raňajky", 160 | "sv": "Frukost" 161 | }, 162 | "C": { 163 | "en": "Closed", 164 | "es": "Cerrada", 165 | "fr": "Fermé", 166 | "ja": "クローズド", 167 | "nl": "Gesloten", 168 | "pt": "Fechada", 169 | "sk": "Uzatvorené", 170 | "sv": "Slutet" 171 | }, 172 | "CAN": { 173 | "en": "Candlelight", 174 | "es": "Luz de una vela", 175 | "fr": "À la chandelle", 176 | "ja": "キャンドル", 177 | "nl": "Candlelight", 178 | "pt": "Luz de Velas", 179 | "sk": "Sviečky", 180 | "sv": "Tända Ljus" 181 | }, 182 | "CF": { 183 | "en": "Child-Friendly", 184 | "es": "Niño amigable", 185 | "fr": "Enfants acceptés", 186 | "ja": "お子さま歓迎", 187 | "nl": "Kindvriendelijk", 188 | "pt": "Amigável para Crianças", 189 | "sk": "Priateľský k deťom", 190 | "sv": "Barnvänligt" 191 | }, 192 | "D": { 193 | "en": "Discussion", 194 | "es": "Discusión", 195 | "fr": "Discussion", 196 | "ja": "ディスカッション", 197 | "nl": "Discussie", 198 | "pt": "Discussão", 199 | "sk": "Diskusia", 200 | "sv": "Diskussion" 201 | }, 202 | "DA": { 203 | "en": "Danish", 204 | "es": "Danés", 205 | "fr": "Danois", 206 | "ja": "デンマーク語", 207 | "nl": "Deens", 208 | "pt": "Dinamarquês", 209 | "sk": "Dánsky", 210 | "sv": "Danska" 211 | }, 212 | "DB": { 213 | "en": "Digital Basket", 214 | "es": "Canasta digital", 215 | "fr": "Panier numérique", 216 | "ja": "電子献金", 217 | "nl": "Digitale mand", 218 | "pt": "Cesto Digital", 219 | "sk": "Digitálny košík", 220 | "sv": "Digital Korg" 221 | }, 222 | "DD": { 223 | "en": "Dual Diagnosis", 224 | "es": "Diagnóstico dual", 225 | "fr": "Double diagnostic", 226 | "ja": "重複診断", 227 | "nl": "Dubbele diagnose", 228 | "pt": "Duplo Diagnóstico", 229 | "sk": "Duálna diagnóza", 230 | "sv": "Dubbel Diagnos" 231 | }, 232 | "DE": { 233 | "en": "German", 234 | "es": "Alemán", 235 | "fr": "Allemand", 236 | "ja": "ドイツ語", 237 | "nl": "Duits", 238 | "pt": "Alemão", 239 | "sk": "Nemecké", 240 | "sv": "Tyska" 241 | }, 242 | "DR": { 243 | "en": "Daily Reflections", 244 | "es": "Reflexiones Diarias", 245 | "fr": "Réflexions quotidiennes", 246 | "ja": "今日を新たに", 247 | "nl": "Dagelijkse weerspiegelingen", 248 | "pt": "Reflexões Diárias", 249 | "sv": "Dagliga Reflektioner", 250 | "sk": "Denné úvahy" 251 | }, 252 | "EL": { 253 | "en": "Greek", 254 | "es": "Griego", 255 | "fr": "Grec", 256 | "ja": "ギリシャ語", 257 | "nl": "Grieks", 258 | "pt": "Grego", 259 | "sk": "Grécke", 260 | "sv": "Grekiska" 261 | }, 262 | "EN": { 263 | "en": "English", 264 | "es": "Inglés", 265 | "fr": "Anglais", 266 | "ja": "英語", 267 | "nl": "Engels", 268 | "pt": "Inglês", 269 | "sk": "Anglické", 270 | "sv": "Engelska" 271 | }, 272 | "FA": { 273 | "en": "Persian", 274 | "es": "Persa", 275 | "fr": "Persan", 276 | "ja": "ペルシア語", 277 | "nl": "Perzisch", 278 | "pt": "Persa", 279 | "sk": "Perzské", 280 | "sv": "Persiska" 281 | }, 282 | "FI": { 283 | "en": "Finnish", 284 | "es": "Finlandés", 285 | "fr": "Finlandais", 286 | "ja": "フィンランド語", 287 | "nl": "Fins", 288 | "pt": "Finlandês", 289 | "sk": "Fínčina", 290 | "sv": "Finska" 291 | }, 292 | "FF": { 293 | "en": "Fragrance Free", 294 | "es": "Sin fragancia", 295 | "fr": "Sans parfum", 296 | "ja": "香水なし", 297 | "nl": "Geen parfum", 298 | "pt": "Sem Perfumes", 299 | "sk": "Bez vône", 300 | "sv": "Parfym Fritt" 301 | }, 302 | "FR": { 303 | "en": "French", 304 | "es": "Francés", 305 | "fr": "Français", 306 | "ja": "フランス語", 307 | "nl": "Frans", 308 | "pt": "Francês", 309 | "sk": "Francúzsky", 310 | "sv": "Franska" 311 | }, 312 | "G": { 313 | "en": "Gay", 314 | "es": "Gay", 315 | "fr": "Gai", 316 | "ja": "ゲイ", 317 | "nl": "Homo", 318 | "pt": "Gay", 319 | "sk": "Gay", 320 | "sv": "Gay" 321 | }, 322 | "GR": { 323 | "en": "Grapevine", 324 | "es": "La Viña", 325 | "fr": "Grapevine", 326 | "ja": "グレープバイン", 327 | "nl": "Wijnstok", 328 | "pt": "Grapevine", 329 | "sk": "Grapevine", 330 | "sv": "Grapevine" 331 | }, 332 | "H": { 333 | "en": "Birthday", 334 | "es": "Cumpleaños", 335 | "fr": "Anniversaire", 336 | "ja": "バースデー", 337 | "nl": "Verjaardag", 338 | "pt": "Aniversário", 339 | "sk": "Narodeniny", 340 | "sv": "Födelsedag" 341 | }, 342 | "HE": { 343 | "en": "Hebrew", 344 | "es": "Hebreo", 345 | "fr": "Hébreu", 346 | "ja": "ヘブライ語", 347 | "nl": "Hebreeuws", 348 | "pt": "Hebreu", 349 | "sk": "Hebrejské", 350 | "sv": "Hebreiska" 351 | }, 352 | "HI": { 353 | "en": "Hindi", 354 | "es": "Hindi", 355 | "fr": "Hindi", 356 | "ja": "ヒンディー語", 357 | "nl": "Hindi", 358 | "pt": "Hindi", 359 | "sk": "Hindi", 360 | "sv": "Hindi" 361 | }, 362 | "HR": { 363 | "en": "Croatian", 364 | "es": "Croata", 365 | "fr": "Croate", 366 | "ja": "クロアチア語", 367 | "nl": "Kroatisch", 368 | "pt": "Croata", 369 | "sk": "Chorvátsky", 370 | "sv": "Kroatiska" 371 | }, 372 | "HU": { 373 | "en": "Hungarian", 374 | "es": "Húngaro", 375 | "fr": "Hongrois", 376 | "ja": "ハンガリー語", 377 | "nl": "Hongaars", 378 | "pt": "Hungaro", 379 | "sk": "Maďarské", 380 | "sv": "Ungerska" 381 | }, 382 | "IS": { 383 | "en": "Icelandic", 384 | "es": "Islandés", 385 | "fr": "Islandais", 386 | "ja": "アイスランド語", 387 | "nl": "IJslands", 388 | "pt": "Islandês", 389 | "sk": "Islanské", 390 | "sv": "Isländska" 391 | }, 392 | "ITA": { 393 | "en": "Italian", 394 | "es": "Italiano", 395 | "fr": "Italien", 396 | "ja": "イタリア語", 397 | "nl": "Italiaans", 398 | "pt": "Italiano", 399 | "sk": "Taliansky", 400 | "sv": "Italienska" 401 | }, 402 | "JA": { 403 | "en": "Japanese", 404 | "es": "Japonés", 405 | "fr": "Japonais", 406 | "ja": "日本語", 407 | "nl": "Japans", 408 | "pt": "Japonês", 409 | "sk": "Japonské", 410 | "sv": "Japanska" 411 | }, 412 | "KA": { 413 | "en": "Georgian", 414 | "es": "Georgiano", 415 | "fr": "Géorgien", 416 | "ja": "ジョージア語", 417 | "nl": "Georgisch", 418 | "pt": "Georgiano", 419 | "sk": "Gruzínske", 420 | "sv": "Georgiska" 421 | }, 422 | "KOR": { 423 | "en": "Korean", 424 | "es": "Coreano", 425 | "fr": "Coréen", 426 | "ja": "韓国語", 427 | "nl": "Koreaans", 428 | "pt": "Coreano", 429 | "sk": "Kórejske", 430 | "sv": "Koreanska" 431 | }, 432 | "L": { 433 | "en": "Lesbian", 434 | "es": "Lesbiana", 435 | "fr": "Lesbienne", 436 | "ja": "レズビアン", 437 | "nl": "Lesbisch", 438 | "pt": "Lésbica", 439 | "sk": "Lesbické", 440 | "sv": "Lesbiskt" 441 | }, 442 | "LGBTQ": { 443 | "en": "LGBTQ", 444 | "es": "LGBTQ", 445 | "fr": "LGBTQ", 446 | "ja": "LGBTQ", 447 | "nl": "LGBTQ", 448 | "pt": "LGBTQ", 449 | "sk": "LGBTQ", 450 | "sv": "HBTQ" 451 | }, 452 | "LIT": { 453 | "en": "Literature", 454 | "es": "Literatura", 455 | "fr": "Publications", 456 | "ja": "書籍", 457 | "nl": "Literatuur", 458 | "pt": "Literatura", 459 | "sk": "Literatúra", 460 | "sv": "Litteratur" 461 | }, 462 | "LS": { 463 | "en": "Living Sober", 464 | "es": "Viviendo Sobrio", 465 | "fr": "Vivre… Sans alcool", 466 | "ja": "リビングソーバー", 467 | "nl": "Sober leven", 468 | "pt": "Viver Sóbrio", 469 | "sk": "Triezvy život", 470 | "sv": "Leva Nyktert" 471 | }, 472 | "LT": { 473 | "en": "Lithuanian", 474 | "es": "Lituano", 475 | "fr": "Lituanien", 476 | "ja": "リトアニア語", 477 | "nl": "Litouws", 478 | "pt": "Lituano", 479 | "sk": "Litovské", 480 | "sv": "Litauiska" 481 | }, 482 | "M": { 483 | "en": "Men", 484 | "es": "Hombres", 485 | "fr": "Hommes", 486 | "ja": "男性", 487 | "nl": "Mannen", 488 | "pt": "Homens", 489 | "sk": "Muži", 490 | "sv": "Mansmöte" 491 | }, 492 | "MED": { 493 | "en": "Meditation", 494 | "es": "Meditación", 495 | "fr": "Méditation", 496 | "ja": "黙想", 497 | "nl": "Meditatie", 498 | "pt": "Meditação", 499 | "sk": "Meditácia", 500 | "sv": "Meditationsmöte" 501 | }, 502 | "ML": { 503 | "en": "Malayalam", 504 | "es": "Malayalam", 505 | "fr": "Malayalam", 506 | "ja": "マラヤーラム語", 507 | "nl": "Malayalam", 508 | "pt": "Malaiala", 509 | "sk": "Malajálamsky", 510 | "sv": "Malayalam" 511 | }, 512 | "MT": { 513 | "en": "Maltese", 514 | "es": "Maltés", 515 | "fr": "Maltais", 516 | "ja": "マルタ語", 517 | "nl": "Maltees", 518 | "pt": "Maltês", 519 | "sk": "Maltézske", 520 | "sv": "Maltesiska" 521 | }, 522 | "N": { 523 | "en": "Native American", 524 | "es": "Nativo Americano", 525 | "fr": "Autochtone", 526 | "ja": "ネイティブアメリカン", 527 | "nl": "Indiaan", 528 | "pt": "Nativo Americano", 529 | "sk": "Domorodí Američania", 530 | "sv": "Ur-amerikanskt" 531 | }, 532 | "NB": { 533 | "en": "Non-Binary", 534 | "es": "No binario", 535 | "fr": "Non binaire", 536 | "ja": "ノンバイナリー", 537 | "nl": "Niet-binair", 538 | "pt": "Não binário", 539 | "sk": "Nebinárne", 540 | "sv": "Icke-binär" 541 | }, 542 | "NDG": { 543 | "en": "Indigenous", 544 | "es": "Indígena", 545 | "fr": "Indigène", 546 | "ja": "先住民", 547 | "nl": "Inheems", 548 | "pt": "Indígena", 549 | "sk": "Domorodé", 550 | "sv": "Urfolkligt" 551 | }, 552 | "NE": { 553 | "en": "Nepali", 554 | "es": "Nepalí", 555 | "fr": "Népalais", 556 | "ja": "ネパール語", 557 | "nl": "Nepalees", 558 | "pt": "Nepalês", 559 | "sk": "Nepálsky", 560 | "sv": "Nepali" 561 | }, 562 | "NL": { 563 | "en": "Dutch", 564 | "es": "Holandés", 565 | "fr": "Néerlandais", 566 | "ja": "オランダ語", 567 | "nl": "Nederlands", 568 | "pt": "Holandês", 569 | "sk": "Holandské", 570 | "sv": "Holländska" 571 | }, 572 | "NO": { 573 | "en": "Norwegian", 574 | "es": "Noruego", 575 | "fr": "Norvégien", 576 | "ja": "ノルウェー語", 577 | "nl": "Noors", 578 | "pt": "Norueguês", 579 | "sk": "Nórsky", 580 | "sv": "Norska" 581 | }, 582 | "O": { 583 | "en": "Open", 584 | "es": "Abierta", 585 | "fr": "Ouvert(e)", 586 | "ja": "オープン", 587 | "nl": "Open", 588 | "pt": "Aberta", 589 | "sk": "Otvorené", 590 | "sv": "Öppet" 591 | }, 592 | "OUT": { 593 | "en": "Outdoor", 594 | "es": "Al aire libre", 595 | "fr": "En plein air", 596 | "ja": "アウトドア", 597 | "nl": "Buiten", 598 | "pt": "Ao ar livre", 599 | "sk": "Vonkajšie", 600 | "sv": "Utomhus" 601 | }, 602 | "P": { 603 | "en": "Professionals", 604 | "es": "Profesionales", 605 | "fr": "Professionnels", 606 | "ja": "職業人", 607 | "nl": "Professionals", 608 | "pt": "Profissionais", 609 | "sk": "Profesionáli", 610 | "sv": "Professionella" 611 | }, 612 | "POA": { 613 | "en": "Proof of Attendance", 614 | "es": "Prueba de Asistencia", 615 | "fr": "Preuve de Présence", 616 | "ja": "出席証明", 617 | "nl": "Bewijs van Aanwezigheid", 618 | "pt": "Comprovante de Presença", 619 | "sk": "Doklad o účasti", 620 | "sv": "Närvarobevis" 621 | }, 622 | "POC": { 623 | "en": "People of Color", 624 | "es": "Gente de color", 625 | "fr": "Gens de couleur", 626 | "ja": "有色人種", 627 | "nl": "Mensen van kleur", 628 | "pt": "Pessoas de Côr", 629 | "sk": "Farební ľudia", 630 | "sv": "Färgade" 631 | }, 632 | "POL": { 633 | "en": "Polish", 634 | "es": "Polaco", 635 | "fr": "Polonais", 636 | "ja": "ポーランド語", 637 | "nl": "Pools", 638 | "pt": "Polaco", 639 | "sk": "Poľské", 640 | "sv": "Polska" 641 | }, 642 | "POR": { 643 | "en": "Portuguese", 644 | "es": "Portugués", 645 | "fr": "Portugais", 646 | "ja": "ポルトガル語", 647 | "nl": "Portugees", 648 | "pt": "Português", 649 | "sk": "Portugalské", 650 | "sv": "Portugisiska" 651 | }, 652 | "PUN": { 653 | "en": "Punjabi", 654 | "es": "Punjabi", 655 | "fr": "Pendjabi", 656 | "ja": "パンジャブ語", 657 | "nl": "Punjabi", 658 | "pt": "Punjabi", 659 | "sk": "Pandžábske", 660 | "sv": "Punjabi" 661 | }, 662 | "RUS": { 663 | "en": "Russian", 664 | "es": "Ruso", 665 | "fr": "Russe", 666 | "ja": "ロシア語", 667 | "nl": "Russisch", 668 | "pt": "Russo", 669 | "sk": "Ruské", 670 | "sv": "Ryska" 671 | }, 672 | "S": { 673 | "en": "Spanish", 674 | "es": "Español", 675 | "fr": "Espagnol", 676 | "ja": "スペイン語", 677 | "nl": "Spaans", 678 | "pt": "Espanhol", 679 | "sk": "Španielské", 680 | "sv": "Spanska" 681 | }, 682 | "SEN": { 683 | "en": "Seniors", 684 | "es": "Personas mayores", 685 | "fr": "Séniors", 686 | "ja": "シニア", 687 | "nl": "Senioren", 688 | "pt": "Séniores", 689 | "sk": "Seniori", 690 | "sv": "Seniorer" 691 | }, 692 | "SK": { 693 | "en": "Slovak", 694 | "es": "Eslovaco", 695 | "fr": "Slovaque", 696 | "ja": "スロバキア語", 697 | "nl": "Slowaaks", 698 | "pt": "Eslovaco", 699 | "sk": "Slovenské", 700 | "sv": "Slovakiska" 701 | }, 702 | "SL": { 703 | "en": "Slovenian", 704 | "es": "Esloveno", 705 | "fr": "Slovène", 706 | "ja": "スロベニア語", 707 | "nl": "Sloveens", 708 | "pt": "Esloveno", 709 | "sk": "Slovinské", 710 | "sv": "Slovenska" 711 | }, 712 | "SM": { 713 | "en": "Smoking Permitted", 714 | "es": "Se permite fumar", 715 | "fr": "Permis de fumer", 716 | "ja": "喫煙可", 717 | "nl": "Roken toegestaan", 718 | "pt": "Permitido Fumar", 719 | "sk": "Fajčenie povolené", 720 | "sv": "Rökning Tillåten" 721 | }, 722 | "SP": { 723 | "en": "Speaker", 724 | "es": "Orador", 725 | "fr": "Conférencier", 726 | "ja": "スピーカー", 727 | "nl": "Spreker", 728 | "pt": "Partilhador", 729 | "sk": "Spíker", 730 | "sv": "Talare" 731 | }, 732 | "ST": { 733 | "en": "Step Study", 734 | "es": "Estudio de pasos", 735 | "fr": "Sur les Étapes", 736 | "ja": "ステップ", 737 | "nl": "Stap studie", 738 | "pt": "Estudo de Passos", 739 | "sk": "Štúdium Krokov", 740 | "sv": "Stegmöte" 741 | }, 742 | "SV": { 743 | "en": "Swedish", 744 | "es": "Sueco", 745 | "fr": "Suédois", 746 | "ja": "スウェーデン語", 747 | "nl": "Zweeds", 748 | "pt": "Sueco", 749 | "sk": "Švédske", 750 | "sv": "Svenska" 751 | }, 752 | "T": { 753 | "en": "Transgender", 754 | "es": "Transgénero", 755 | "fr": "Transgenre", 756 | "ja": "トランスジェンダー", 757 | "nl": "Transgender", 758 | "pt": "Transgénero", 759 | "sk": "Transgender", 760 | "sv": "Transpersoner" 761 | }, 762 | "TC": { 763 | "en": "Location Temporarily Closed", 764 | "es": "Ubicación temporalmente cerrada", 765 | "fr": "Emplacement temporairement fermé", 766 | "ja": "一時的休止中", 767 | "nl": "Locatie tijdelijk gesloten", 768 | "pt": "Local Temporáriamente Encerrado", 769 | "sk": "Miesto dočasne zatvorené", 770 | "sv": "Tillfälligt Stängt" 771 | }, 772 | "TH": { 773 | "en": "Thai", 774 | "es": "Tailandés", 775 | "fr": "Thaï", 776 | "ja": "タイ語", 777 | "nl": "Thais", 778 | "pt": "Tailandês", 779 | "sk": "Thajské", 780 | "sv": "Thailändska" 781 | }, 782 | "TL": { 783 | "en": "Tagalog", 784 | "es": "Tagalo", 785 | "fr": "Tagalog", 786 | "ja": "タガログ語", 787 | "nl": "Tagalog", 788 | "pt": "Tagalo", 789 | "sk": "Tagalské", 790 | "sv": "Tagalog" 791 | }, 792 | "TR": { 793 | "en": "Tradition Study", 794 | "es": "Estudio de tradicion", 795 | "fr": "Étude des Traditions", 796 | "ja": "伝統", 797 | "nl": "Traditie Studie", 798 | "pt": "Estudo de Tradições", 799 | "sk": "Tradičné štúdium", 800 | "sv": "Traditionsmöte" 801 | }, 802 | "TUR": { 803 | "en": "Turkish", 804 | "es": "Turco", 805 | "fr": "Turc", 806 | "ja": "トルコ語", 807 | "nl": "Turks", 808 | "pt": "Turco", 809 | "sk": "Turecký", 810 | "sv": "Turkiska" 811 | }, 812 | "UK": { 813 | "en": "Ukrainian", 814 | "es": "Ucraniano", 815 | "fr": "Ukrainien", 816 | "ja": "ウクライナ語", 817 | "nl": "Oekraïens", 818 | "pt": "Ucraniano", 819 | "sk": "Ukrajinské", 820 | "sv": "Ukrainska" 821 | }, 822 | "W": { 823 | "en": "Women", 824 | "es": "Mujer", 825 | "fr": "Femmes", 826 | "ja": "女性", 827 | "nl": "Vrouwen", 828 | "pt": "Mulheres", 829 | "sk": "Ženy", 830 | "sv": "Kvinnomöte" 831 | }, 832 | "X": { 833 | "en": "Wheelchair Access", 834 | "es": "Acceso en silla de ruedas", 835 | "fr": "Accès aux fauteuils roulants", 836 | "ja": "車いすアクセス", 837 | "nl": "Toegankelijk voor rolstoelgebruikers", 838 | "pt": "Acesso a Cadeiras de Rodas", 839 | "sk": "Prístup pre vozíčkarov", 840 | "sv": "Handikappanpassat" 841 | }, 842 | "XB": { 843 | "en": "Wheelchair-Accessible Bathroom", 844 | "es": "Baño accesible para sillas de ruedas", 845 | "fr": "Toilettes accessibles aux fauteuils roulants", 846 | "ja": "車いす使用者用トイレ", 847 | "nl": "Rolstoeltoegankelijke badkamer", 848 | "pt": "WC com Acesso a Cadeiras de Rodas", 849 | "sk": "Bezbariérová kúpeľňa", 850 | "sv": "Handikappanpassad WC" 851 | }, 852 | "XT": { 853 | "en": "Cross Talk Permitted", 854 | "es": "Se permite opinar", 855 | "fr": "Conversation croisée permise", 856 | "ja": "クロストーク可能", 857 | "nl": "Cross-sharen toegestaan", 858 | "pt": "Prtilhas Cruzadas Permitidas", 859 | "sk": "Cross Talk povolený", 860 | "sv": "Kommentarer Tilltåtna" 861 | }, 862 | "Y": { 863 | "en": "Young People", 864 | "es": "Gente joven", 865 | "fr": "Jeunes", 866 | "ja": "ヤング", 867 | "nl": "Jongeren", 868 | "pt": "Jovens", 869 | "sk": "Mladí ľudia", 870 | "sv": "Young People" 871 | } 872 | } 873 | -------------------------------------------------------------------------------- /import-scripts/amarillo/meeting-guide.php: -------------------------------------------------------------------------------- 1 | getMessage()); 17 | } 18 | 19 | //error handling 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 21 | 22 | //select data 23 | try { 24 | $result = $pdo->query('SELECT * FROM scheds'); 25 | } catch (PDOException $e) { 26 | die('SQL query failed: ' . $e->getMessage()); 27 | } 28 | 29 | //debugging 30 | function dd($obj) { 31 | echo '
';
 32 | 	print_r($obj);
 33 | 	exit;
 34 | }
 35 | 
 36 | //convert local meeting type to meeting guide type
 37 | function meetingGuideType($type) {
 38 | 	global $type_lookup;
 39 | 	return array_key_exists($type, $type_lookup) ? $type_lookup[$type] : null;
 40 | }
 41 | 
 42 | //define array to return
 43 | $meetings = array();
 44 | 
 45 | //will use later to convert days to integers
 46 | $day_lookup = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 47 | 
 48 | //will use later to convert local types to meeting guide types
 49 | $type_lookup = array(
 50 | 	'O' => 'O',
 51 | 	'C' => 'C',
 52 | 	'D' => 'D',
 53 | 	'BB' => 'B',
 54 | 	'S' => 'SP',
 55 | 	'SS' => 'ST',
 56 | 	'M' => 'M',
 57 | 	'W' => 'W',
 58 | 	'ABSI' => 'ABSI',
 59 | 	'NS' => 'NS',
 60 | );
 61 | 
 62 | foreach ($result as $r) {
 63 | 
 64 | 	//replace string day with integer
 65 | 	if ($r['day'] == 'Everyday') {
 66 | 		$day = range(0, 6);
 67 | 	} elseif (in_array($r['day'], $day_lookup)) {
 68 | 		$day = array_search($r['day'], $day_lookup);
 69 | 	} else {
 70 | 		continue;
 71 | 	}
 72 | 
 73 | 	//turn types column into array of meeting guide type codes
 74 | 	$types = explode(' ', str_replace(array(',', '*'), ' ', $r['type']));
 75 | 	$types = array_values(array_filter(array_map('meetingGuideType', $types)));
 76 | 
 77 | 	//format address, split notes off
 78 | 	$address = $r['address'];
 79 | 
 80 | 	//return a key
 81 | 	$meetings[] = array(
 82 | 		'slug' => $r['id'],
 83 | 		'city' => $r['city'],
 84 | 		'day' => $day,
 85 | 		'time' => date('H:i', strtotime($r['timeampm'])),
 86 | 		//'timeampm' => $r['timeampm'],
 87 | 		//'type' => $r['type'],
 88 | 		'types' => $types,
 89 | 		'address' => $address,
 90 | 		'phone' => $r['phone'],
 91 | 		'name' => $r['groupname'],
 92 | 		'state' => 'TX',
 93 | 		'country' => 'US',
 94 | 	);
 95 | }
 96 | 
 97 | //encode JSON
 98 | $return = json_encode($meetings);
 99 | if (json_last_error()) {
100 | 	die('JSON error: ' . json_last_error_msg());
101 | }
102 | 
103 | //make sure headers haven't already been sent, will cause error
104 | if (headers_sent()) {
105 | 	die('Error: headers already sent!');
106 | }
107 | 
108 | //output
109 | header('Content-type: application/json; charset=utf-8');
110 | echo $return;


--------------------------------------------------------------------------------
/import-scripts/annapolis/annapolis.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 37 | }
 38 | 
 39 | //error handling
 40 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 41 | 
 42 | //select data
 43 | try {
 44 | 	$result = $pdo->query($sql);
 45 | } catch (PDOException $e) {
 46 |     die('SQL query failed: ' . $e->getMessage());
 47 | }
 48 | 
 49 | //type definitions
 50 | $decode_types = array(
 51 | 	'A' => 'AL-AN',	//concurrent with al-anon
 52 | 	'C' => 'C',		//closed
 53 | 	'G' => 'W',		//women
 54 | 	'M' => 'M',		//men (doesn't exist yet)
 55 | 	//'S' => 'S', 	//no court slips (don't have a type for this)
 56 | 	'T' => 'AL',	//alateen
 57 | 	'W' => 'X',		//wheelchair accessible
 58 | 	'Beginner' => 'BE',
 59 | 	'Beginners Step' => 'BE',
 60 | 	'Discussion' => 'D',
 61 | 	'Discussion - Grapevine' => 'GR',
 62 | 	'Korean' => 'KOR',
 63 | 	'Lit-As Bill Sees It' => 'LIT',
 64 | 	'Lit-Big Book' => 'LIT',
 65 | 	'Lit-Came To Believe' => 'LIT',
 66 | 	'Lit-Daily Reflections' => 'LIT',
 67 | 	'Lit-How It Works' => 'LIT',
 68 | 	'Literature' => 'LIT',
 69 | 	'Meditation' => 'MED',
 70 | 	'Spanish' => 'S',
 71 | 	'Speaker' => 'SP',
 72 | 	'Step' => 'ST',
 73 | 	'Spanish' => 'S',
 74 | );
 75 | 
 76 | //fetch data
 77 | $return = array();
 78 | foreach ($result as $row) {
 79 | 	
 80 | 	//trim all values
 81 | 	$row = array_map('trim', $row);
 82 | 	
 83 | 	//set types
 84 | 	$types = array();
 85 | 	if (array_key_exists($row['language'], $decode_types)) $types[] = $decode_types[$row['language']];
 86 | 	if (array_key_exists($row['mtg_type'], $decode_types)) $types[] = $decode_types[$row['mtg_type']];
 87 | 	$codes = str_split($row['Code']);
 88 | 	foreach ($codes as $code) {
 89 | 		if (array_key_exists($code, $decode_types)) $types[] = $decode_types[$code];
 90 | 	}
 91 | 	
 92 | 	//append address 2 to location notes
 93 | 	if (!empty($row['addr2'])) {
 94 | 		if (!empty($row['notes'])) $row['notes'] .= '
'; 95 | $row['notes'] .= $row['addr2']; 96 | } 97 | 98 | //build array 99 | $return[] = array( 100 | 'slug' => $row['id'], 101 | 'day' => $row['day'], 102 | 'time' => substr($row['time'], 0, 2) . ':' . substr($row['time'], 2, 2), 103 | 'notes' => $row['mtg_notes'], 104 | 'types' => $types, 105 | 'name' => $row['gp_name'], 106 | 'location' => $row['loc_name'], 107 | 'address' => $row['addr1'], 108 | 'city' => $row['city'], 109 | 'state' => 'MD', 110 | 'country' => 'US', 111 | 'location_notes' => $row['notes'], 112 | 'region' => $row['city'], 113 | ); 114 | } 115 | 116 | 117 | //encode JSON 118 | $return = json_encode($return); 119 | if (json_last_error()) { 120 | die('JSON error: ' . json_last_error_msg()); 121 | } 122 | 123 | //make sure headers haven't already been sent, will cause error 124 | if (headers_sent()) { 125 | die('Error: headers already sent!'); 126 | } 127 | 128 | //output 129 | header('Content-type: application/json; charset=utf-8'); 130 | echo $return; 131 | -------------------------------------------------------------------------------- /import-scripts/baltimore/12-step-meeting-list.php: -------------------------------------------------------------------------------- 1 | 'Sunday', 'Mon' => 'Monday', 'Tue' => 'Tuesday', 'Wed' => 'Wednesday', 'Thu' => 'Thursday', 'Fri' => 'Friday', 'Sat' => 'Saturday'); 11 | $delimiters = array('@', ';', '&', '('); 12 | array_shift($meetings); 13 | 14 | //loop through the input 15 | foreach($meetings as $meeting) { 16 | //easy ones 17 | $day = array_key_exists($meeting[7], $decode_days) ? $decode_days[$meeting[7]] : $meeting[7]; 18 | $time = $meeting[9]; 19 | $name = $meeting[1]; 20 | $location = $meeting[2]; 21 | $region = $meeting[4]; 22 | $postal_code = $meeting[5]; 23 | $location_notes = ''; 24 | $notes = $meeting[13]; 25 | 26 | //if region has a slash, just take the first part and hope google figures it out 27 | if ($pos = strpos($region, '/')) { 28 | $city = substr($region, 0, $pos); 29 | } else { 30 | $city = $region; 31 | } 32 | 33 | //split address at delimiter if present 34 | $address = $meeting[3]; 35 | foreach ($delimiters as $delimiter) { 36 | if ($pos = strpos($address, $delimiter)) { 37 | $location_notes .= substr($address, $pos); 38 | $address = substr($address, 0, $pos); 39 | } 40 | } 41 | 42 | //build types from a number of columns 43 | $types = array(); 44 | 45 | //open column 46 | if ($meeting[10] == 'O') { 47 | $types[] = 'Open'; 48 | } elseif ($meeting[10] == 'C') { 49 | $types[] = 'Closed'; 50 | } 51 | 52 | //smoke, type and notes 53 | $type_values = explode(' ', strtoupper($meeting[11] . ' ' . $meeting[12] . ' ' . str_replace(',', ' ', $meeting[13]))); 54 | foreach ($type_values as $value) { 55 | if ($value == 'AS BILL SEES IT') $types[] = 'As Bill Sees It'; 56 | if ($value == 'BB') $types[] = 'Big Book'; 57 | if ($value == 'CHIP') $types[] = 'Birthday'; 58 | if ($value == 'D') $types[] = 'Discussion'; 59 | if ($value == 'DAILY REFLECTIONS') $types[] = 'Daily Reflections'; 60 | if ($value == 'DISCUSSION') $types[] = 'Discussion'; 61 | if ($value == 'G') $types[] = 'LGBTQ'; 62 | if ($value == 'LGBTQ') $types[] = 'LGBTQ'; 63 | if ($value == 'LIT') $types[] = 'Literature'; 64 | if ($value == 'MENS') $types[] = 'Men'; 65 | if ($value == 'PROM') $types[] = 'Promises'; 66 | if ($value == 'SPK') $types[] = 'Speaker'; 67 | if ($value == 'SPANISH') $types[] = 'Spanish'; 68 | if ($value == 'STEP') $types[] = 'Step Meeting'; 69 | if ($value == 'TOPIC') $types[] = 'Discussion'; 70 | if ($value == 'TRAD') $types[] = 'Traditions'; 71 | if ($value == 'W') $types[] = 'Women'; 72 | if ($value == 'WOMENS') $types[] = 'Women'; 73 | if ($value == 'YP') $types[] = 'Young People'; 74 | } 75 | 76 | //h column 77 | if ($meeting[14] == 'H') { 78 | $types[] = 'Wheelchair Access'; 79 | } 80 | $types = implode(',', $types); 81 | 82 | //add to array 83 | $return[] = compact('day', 'time', 'name', 'location', 'address', 'city', 'state', 'postal_code', 'country', 'types', 'notes', 'location_notes', 'region'); 84 | } 85 | 86 | //go back to non-associative format 87 | $meetings = array(); 88 | $meetings[] = array_keys($return[0]); 89 | foreach ($return as $row) { 90 | $meetings[] = array_values($row); 91 | } 92 | return $meetings; 93 | } 94 | -------------------------------------------------------------------------------- /import-scripts/baltimore/meetings-api.php: -------------------------------------------------------------------------------- 1 | "Group ID"'; //checking because header row present in data sample 14 | 15 | class Meeting 16 | { 17 | function __construct( $row ) 18 | { 19 | 20 | $this->name = $row->mName; 21 | $this->time = $row->mInternational; 22 | if ($this->time == '2400') $this->time = '23:59'; //ad-hoc replacement 23 | $this->day = $row->mDayNo -1; //day should be 0 - 6 (sun - sat) 24 | $this->slug = $row->mID . '-' . $this->day . '-' . str_replace(':', '', $this->time); //id by itself is not unique 25 | $this->notes = $row->mNotes; 26 | $this->location = $row->mAdd1; 27 | 28 | //fixing addresses that have extra stuff in them 29 | if ($pos = strpos($row->mAdd2, ' (')) { 30 | $this->address = substr($row->mAdd2, 0, $pos); 31 | $this->notes .= substr($row->mAdd2, $pos); 32 | } elseif ($pos = strpos($row->mAdd2, ';')) { 33 | $this->address = substr($row->mAdd2, 0, $pos); 34 | $this->notes .= substr($row->mAdd2, $pos); 35 | } elseif ($pos = strpos($row->mAdd2, ', ')) { 36 | $this->address = substr($row->mAdd2, 0, $pos); 37 | $this->notes .= substr($row->mAdd2, $pos); 38 | } elseif ($pos = strpos($row->mAdd2, '- ')) { 39 | $this->address = substr($row->mAdd2, 0, $pos); 40 | $this->notes .= substr($row->mAdd2, $pos); 41 | } elseif ($pos = strpos($row->mAdd2, '-rear')) { //don't want to simply match - since it's correct in many addresses 42 | $this->address = substr($row->mAdd2, 0, $pos); 43 | $this->notes .= substr($row->mAdd2, $pos); 44 | } elseif ($pos = strpos($row->mAdd2, '-near')) { //don't want to simply match - since it's correct in many addresses 45 | $this->address = substr($row->mAdd2, 0, $pos); 46 | $this->notes .= substr($row->mAdd2, $pos); 47 | } elseif ($pos = strpos($row->mAdd2, '-Roland')) { //don't want to simply match - since it's correct in many addresses 48 | $this->address = substr($row->mAdd2, 0, $pos); 49 | $this->notes .= substr($row->mAdd2, $pos); 50 | } elseif ($pos = strpos($row->mAdd2, '-Smith')) { //don't want to simply match - since it's correct in many addresses 51 | $this->address = substr($row->mAdd2, 0, $pos); 52 | $this->notes .= substr($row->mAdd2, $pos); 53 | } elseif ($pos = strpos($row->mAdd2, ' @ ')) { 54 | $this->address = substr($row->mAdd2, 0, $pos); 55 | $this->notes .= substr($row->mAdd2, $pos); 56 | } elseif ($pos = strpos($row->mAdd2, ' bet. ')) { 57 | $this->address = substr($row->mAdd2, 0, $pos); 58 | $this->notes .= substr($row->mAdd2, $pos); 59 | } elseif ($pos = strpos($row->mAdd2, ' at ')) { 60 | $this->address = substr($row->mAdd2, 0, $pos); 61 | $this->notes .= substr($row->mAdd2, $pos); 62 | } elseif ($pos = strpos($row->mAdd2, ' & ')) { 63 | $this->address = substr($row->mAdd2, 0, $pos); 64 | $this->notes .= substr($row->mAdd2, $pos); 65 | } else { 66 | $this->address = $row->mAdd2; 67 | } 68 | 69 | //ad-hoc replacements 70 | $this->address = str_replace(' La.', ' Lane', $this->address); 71 | $this->address = str_replace('Comm Life Ctr', '961 Johnsville Road', $this->address); 72 | $this->address = str_replace('Hanover Price', 'Hanover Pike', $this->address); 73 | 74 | //fixing cities that have extra stuff 75 | if ($pos = strpos($row->mCity, '/')) { 76 | $this->city = substr($row->mCity, 0, $pos); 77 | } else { 78 | $this->city = $row->mCity; 79 | } 80 | 81 | $this->state = 'MD'; 82 | $this->postal_code = $row->mZip; 83 | $this->country = 'US'; 84 | //list($this->latitude, $this->longitude) = explode(',', trim($row->mSpecial)); 85 | $this->timezone = 'America/New_York'; 86 | 87 | //build array of meeting codes 88 | $this->types = array(); 89 | if ($row->mOpen == 'O') { 90 | $this->types[] = 'O'; 91 | } elseif ($row->mOpen == 'C') { 92 | $this->types[] = 'C'; 93 | } 94 | if (stristr($row->mNotes, 'big book')) $this->types[] = 'BB'; 95 | if (stristr($row->mNotes, 'chip')) $this->types[] = 'H'; 96 | if (stristr($row->mNotes, 'gay')) $this->types[] = 'G'; 97 | if (stristr($row->mNotes, 'grapevine')) $this->types[] = 'GR'; 98 | if (stristr($row->mNotes, 'spanish')) $this->types[] = 'S'; 99 | if (stristr($row->mNotes, 'step')) $this->types[] = 'ST'; 100 | if (stristr($row->mNotes, 'trad')) $this->types[] = 'TR'; 101 | if (stristr($row->mNotes, 'women')) { 102 | $this->types[] = 'W'; 103 | } elseif (stristr($row->mNotes, 'men')) { 104 | $this->types[] = 'M'; 105 | } 106 | if ($row->mAccess == 'H') $types[] = 'X'; 107 | if ($row->mType == 'Discussion') { 108 | $this->types[] = 'D'; 109 | } elseif ($row->mType == 'Speaker') { 110 | $this->types[] = 'SP'; 111 | } 112 | } 113 | } 114 | 115 | $link = mysqli_connect($server, $username, $password, $database) or die('could not connect to database server'); 116 | 117 | $result = mysqli_query($link, $sql); 118 | if (!$result) die(mysqli_error($link)); 119 | 120 | $data = array(); 121 | while ($row = mysqli_fetch_object($result)) { 122 | $obj = new Meeting($row); 123 | if (empty($obj->address)) continue; //checking because some rows are empty, looks like import issue maybe 124 | array_push($data, $obj); 125 | } 126 | 127 | header('Content-type: application/json; charset=utf-8'); 128 | echo json_encode($data); 129 | 130 | mysqli_free_result($result); 131 | mysqli_close($link); 132 | 133 | 134 | function dd($obj) { 135 | echo '
';
136 | 	print_r($obj);
137 | 	exit;
138 | }


--------------------------------------------------------------------------------
/import-scripts/baltimore/style.css:
--------------------------------------------------------------------------------
 1 | /*
 2 | Theme Name: Avada Child
 3 | Description: Child theme for Avada theme
 4 | Author: ThemeFusion
 5 | Author URI: https://theme-fusion.com
 6 | Template: Avada
 7 | Version: 1.0.0
 8 | Text Domain:  Avada
 9 | */
10 | 
11 | /* hide you are here on meeting pages */
12 | body.post-type-archive-tsml_meeting .fusion-page-title-bar, 
13 | body.single-tsml_meeting .fusion-page-title-bar,
14 | body.single-tsml_location .fusion-page-title-bar
15 | { display: none; }
16 | 
17 | /* better margins on meeting pages */
18 | body.post-type-archive-tsml_meeting #main, 
19 | body.single-tsml_meeting #main,
20 | body.single-tsml_location #main
21 | { padding: 20px 0 0; }


--------------------------------------------------------------------------------
/import-scripts/broward-county/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | ';
  6 | 	print_r($obj);
  7 | 	exit;
  8 | }
  9 | 
 10 | //need these for looping
 11 | $days = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
 12 | $type_lookup = array(
 13 |     'O' => 'O',
 14 |     'C' => 'C',
 15 |     'ag' => 'A',
 16 |     'AB' => 'ABSI',
 17 |     'BG' => 'BE',
 18 |     'BB' => 'B',
 19 |     'CB' => 'LIT',
 20 |     //'CC' => 'Chair's Choice',
 21 |     'DR' => 'DR',
 22 |     'D' => 'D',
 23 |     'FR' => 'FR',
 24 |     'g' => 'G',
 25 |     'GV' => 'GR',
 26 |     'LT' => 'LIT',
 27 |     'LS' => 'LS',
 28 |     'M' => 'MED',
 29 |     'm' => 'M',
 30 |     'PG' => 'POR',
 31 |     //'RF' => 'Rotating Format',
 32 |     'RU' => 'RUS',
 33 |     'SH' => 'S',
 34 |     'SP' => 'SP',
 35 |     'SPD' => array('SP', 'D'),
 36 |     'ST' => 'ST',
 37 |     'SS' => 'ST',
 38 |     'STR' => array('ST', 'TR'),
 39 |     'TR' => 'TR',
 40 |     'w' => 'W',
 41 |     'YP' => 'Y',
 42 | );
 43 | 
 44 | if (file_exists('wp-config.php')) {
 45 | 	include('wp-config.php');
 46 | } else {
 47 | 	define('DB_NAME', 'broward');
 48 | 	define('DB_USER', 'root');
 49 | 	define('DB_PASSWORD', '');
 50 | 	define('DB_HOST', 'localhost');
 51 | 	$table_prefix  = 'aabci_';
 52 | }
 53 | 
 54 | //make sure errors are being reported
 55 | error_reporting(E_ALL);
 56 | 
 57 | //connect to database
 58 | try {
 59 |     $pdo = new PDO('mysql:charset=UTF8;dbname=' . DB_NAME . ';host=' . DB_HOST, DB_USER, DB_PASSWORD);
 60 | } catch (PDOException $e) {
 61 |     die('Database connection failed: ' . $e->getMessage());
 62 | }
 63 | 
 64 | //error handling
 65 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 66 | $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
 67 | 
 68 | //select location data
 69 | try {
 70 | 	$result = $pdo->query('SELECT ID, post_title, post_name, post_modified_gmt FROM ' . $table_prefix . 'posts WHERE post_type = "locations" AND post_status = "publish"');
 71 | 	//$meetings = $pdo->query('SELECT ID, post_title, post_modified_gmt FROM ' . $table_prefix . 'posts WHERE post_type = "meetings" AND post_status = "publish"');
 72 | 	//$meta = $pdo->query('SELECT post_id, meta_key, meta_value FROM ' . $table_prefix . 'postmeta WHERE post_id IN (SELECT ID FROM ' . $table_prefix . 'posts WHERE meta_key NOT LIKE "\_%" AND post_type IN ("meetings", "locations"))');
 73 | } catch (PDOException $e) {
 74 |     die('SQL query failed: ' . $e->getMessage());
 75 | }
 76 | 
 77 | //define some arrays
 78 | $locations = $groups = $meetings = array();
 79 | 
 80 | //build an array of locations, keyed by id
 81 | foreach ($result as $r) {
 82 | 	$locations[$r->ID] = array(
 83 | 		'location' => $r->post_title,
 84 | 		'location_slug' => $r->post_name,
 85 | 		'location_updated' =>  $r->post_modified_gmt,
 86 | 	);
 87 | }
 88 | 
 89 | //get location metadata
 90 | $result = $pdo->query('SELECT post_id, meta_key, meta_value FROM ' . $table_prefix . 'postmeta WHERE meta_key IN ("street_address", "suite_number", "city", "state", "zip", "accessible_venue") AND post_id IN (' . implode(',', array_keys($locations)) . ')');
 91 | 
 92 | //attach meta values to locations
 93 | foreach ($result as $r) {
 94 | 	$locations[$r->post_id][$r->meta_key] = $r->meta_value;
 95 | }
 96 | 
 97 | //get meetings
 98 | $result = $pdo->query('SELECT ID, post_title, post_modified_gmt FROM ' . $table_prefix . 'posts WHERE post_type = "meetings" AND post_status = "publish"');
 99 | 
100 | //build an array of meetings, keyed by id
101 | foreach ($result as $r) {
102 | 	$groups[$r->ID] = array(
103 | 		'name' => $r->post_title,
104 | 		'meeting_updated' =>  $r->post_modified_gmt,
105 | 	);
106 | }
107 | 
108 | //get group metadata
109 | $result = $pdo->query('SELECT post_id, meta_key, meta_value FROM ' . $table_prefix . 'postmeta WHERE meta_key NOT LIKE "\_%" AND post_id IN (' . implode(',', array_keys($groups)) . ')');
110 | 
111 | //attach meta values to group
112 | foreach ($result as $r) {
113 | 	if ($r->meta_key == 'meeting_location') {
114 | 		//attach location info to meeting
115 | 		if (array_key_exists($r->meta_value, $locations)) {
116 | 			$groups[$r->post_id] = array_merge($groups[$r->post_id], $locations[$r->meta_value]);
117 | 		}
118 | 	}
119 | 	$groups[$r->post_id][$r->meta_key] = $r->meta_value;	
120 | }
121 | 
122 | //go through the groups and add to the meetings array in the right format
123 | foreach ($groups as $group_id => $group) {
124 | 	foreach ($days as $day_index => $day) {
125 | 		if (!empty($group[$day . '_new'])) {
126 | 			for ($i = 0; $i < $group[$day . '_new']; $i++) {
127 | 
128 | 				//decode types
129 | 				$types = array();
130 | 				if ($group['accessible_venue'] == '1') $types[] = 'X';				
131 | 				if (isset($group[$day . '_new_' . $i . '_meeting_type'])) {
132 | 					$undecoded_types = unserialize($group[$day . '_new_' . $i . '_meeting_type']);
133 | 					foreach ($undecoded_types as $type) {
134 | 						if (array_key_exists($type, $type_lookup)) {
135 | 							if (is_array($type_lookup[$type])) {
136 | 								$types = array_merge($types, $type_lookup[$type]);
137 | 							} else {
138 | 								$types[] = $type_lookup[$type];
139 | 							}
140 | 						}
141 | 					}
142 | 				}
143 | 
144 | 				//append meeting to meetings array
145 | 				$meetings[] = array(
146 | 					'slug' => $group_id . '_' . $day . '_' . $i,
147 | 					'name' => $group['name'],
148 | 					'location' => $group['location'],
149 | 					'updated' => max($group['meeting_updated'], $group['location_updated']),
150 | 					'city' => $group['city'],
151 | 					'state' => $group['state'],
152 | 					'address' => $group['street_address'],
153 | 					'notes' => $group['suite_number'],
154 | 					'postal_code' => $group['zip'],
155 | 					'day' => $day_index,
156 | 					'time' => $group[$day . '_new_' . $i . '_meeting_time'],
157 | 					'types' => $types,
158 | 					'url' => 'https://aabroward.org/locations/' . $group['location_slug'] . '/',
159 | 				);
160 | 
161 | 			}
162 | 		}
163 | 	}
164 | }
165 | 
166 | //encode JSON
167 | $return = json_encode($meetings);
168 | if (json_last_error()) {
169 | 	die('JSON error: ' . json_last_error_msg());
170 | }
171 | 
172 | //make sure headers haven't already been sent, will cause error
173 | if (headers_sent()) {
174 | 	die('Error: headers already sent!');
175 | }
176 | 
177 | //output
178 | header('Content-type: application/json; charset=utf-8');
179 | echo $return;
180 | 


--------------------------------------------------------------------------------
/import-scripts/calgary/calgary-meeting-guide.php:
--------------------------------------------------------------------------------
  1 | get_results('SELECT
 24 | 		ID,
 25 | 		post_title,
 26 | 		post_name,
 27 | 		post_modified_gmt
 28 | 	FROM al_posts 
 29 | 	WHERE post_type = "alco-meetings" AND post_status = "publish"');
 30 | 	
 31 | 	//loop through and create a keyed array of meetings
 32 | 	foreach ($posts as $post) {
 33 | 		$meetings[$post->ID] = array(
 34 | 			'name' => $post->post_title,
 35 | 			'slug' => $post->post_name,
 36 | 			'updated' => $post->post_modified_gmt,	
 37 | 			'types' => array(),
 38 | 		);
 39 | 	}
 40 | 	
 41 | 	//get metadata
 42 | 	$meta = $wpdb->get_results('SELECT 
 43 | 		post_id, 
 44 | 		meta_key, 
 45 | 		meta_value 
 46 | 	FROM al_postmeta
 47 | 	WHERE post_id IN (' . implode(',', array_keys($meetings)) . ') AND 
 48 | 		meta_key IN ("date-time", "address", "decri", "code", "cityq", "landmark")');
 49 | 
 50 | 	//loop through metadata and attach to meeting
 51 | 	foreach ($meta as $value) {
 52 | 		$value->meta_value = trim($value->meta_value);
 53 | 		if ($value->meta_key == 'date-time') {
 54 | 			//fix certain times
 55 | 			$value->meta_value = strtolower($value->meta_value);
 56 | 			$value->meta_value = str_replace('noon', 'pm', $value->meta_value);
 57 | 			$value->meta_value = str_replace('midnight', 'am', $value->meta_value);
 58 | 			$meetings[$value->post_id]['time'] = $value->meta_value;
 59 | 			//$values[] = $value->meta_value;
 60 | 		} elseif ($value->meta_key == 'address') {
 61 | 			$meetings[$value->post_id]['address'] = $value->meta_value;
 62 | 		} elseif ($value->meta_key == 'decri') {
 63 | 			$meetings[$value->post_id]['notes'] = $value->meta_value;
 64 | 		} elseif ($value->meta_key == 'code') {
 65 | 		} elseif ($value->meta_key == 'cityq') {
 66 | 			$meetings[$value->post_id]['region'] = $value->meta_value;
 67 | 		} elseif ($value->meta_key == 'landmark') {
 68 | 			$meetings[$value->post_id]['location'] = $value->meta_value;
 69 | 		}
 70 | 	}
 71 | 		
 72 | 	//grab terms
 73 | 	$terms = $wpdb->get_results('SELECT  
 74 | 		r.object_id,
 75 | 		t.`name`,
 76 | 		x.taxonomy
 77 | 	FROM al_term_relationships r 
 78 | 	JOIN al_term_taxonomy x ON r.term_taxonomy_id = x.term_taxonomy_id
 79 | 	JOIN al_terms t ON x.term_id = t.term_id
 80 | 	WHERE object_id 	IN (' . implode(',', array_keys($meetings)) . ')');
 81 | 	
 82 | 	//day options
 83 | 	$days = array(
 84 | 		'sunday' => 0,
 85 | 		'monday' => 1,
 86 | 		'tuesday' => 2,
 87 | 		'wednesday' => 3,
 88 | 		'thursday' => 4,
 89 | 		'friday' => 5,
 90 | 		'saturday' => 6,
 91 | 	);
 92 | 	
 93 | 	foreach ($terms as $term) {
 94 | 		$term->name = strtolower(trim($term->name));
 95 | 		if ($term->taxonomy == 'day-of-week') {
 96 | 			if (array_key_exists($term->name, $days)) {
 97 | 				$meetings[$term->object_id]['day'] = $days[$term->name];
 98 | 			}
 99 | 		} elseif ($term->taxonomy == 'meeting-type') {
100 | 			if ($term->name == 'closed meeting') {
101 | 				$meetings[$term->object_id]['types'][] = 'C';
102 | 			} elseif ($term->name == 'gay/lesbian') {
103 | 				$meetings[$term->object_id]['types'][] = 'LGBTQ';
104 | 			} elseif ($term->name == 'men only') {
105 | 				$meetings[$term->object_id]['types'][] = 'M';
106 | 			} elseif ($term->name == 'open meeting') {
107 | 				$meetings[$term->object_id]['types'][] = 'O';
108 | 			} elseif ($term->name == 'polish speaking') {
109 | 				$meetings[$term->object_id]['types'][] = 'POL';
110 | 			} elseif ($term->name == 'spanish speaking') {
111 | 				$meetings[$term->object_id]['types'][] = 'S';
112 | 			} elseif ($term->name == 'wheelchair accessible') {
113 | 				$meetings[$term->object_id]['types'][] = 'X';
114 | 			} elseif ($term->name == 'women only') {
115 | 				$meetings[$term->object_id]['types'][] = 'W';
116 | 			}
117 | 		} elseif ($term->taxonomy == 'location-meeting') {
118 | 			//potential region (northeast, northwest, out of town) -- think city name is better
119 | 			//$values[] = $term->name;
120 | 		}
121 | 	}
122 | 	
123 | 	//debugging: show collected values
124 | 	if (count($values)) {
125 | 		sort($values);
126 | 		wp_send_json(array_unique($values));
127 | 	}
128 | 	
129 | 	//remove any that don't have a day or an address
130 | 	foreach ($meetings as $meeting_id => $meeting) {
131 | 		if (!isset($meeting['day'])) unset($meetings[$meeting_id]);
132 | 		if (empty($meeting['address'])) unset($meetings[$meeting_id]);
133 | 	}
134 | 	
135 | 	wp_send_json(array_values($meetings));
136 | }
137 | 


--------------------------------------------------------------------------------
/import-scripts/cape-atlantic/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | get_results('SELECT 
 26 | 			SUBSTRING_INDEX(p.post_title, ": ", -1) name,
 27 | 			p.post_name slug,
 28 | 			TIME_FORMAT(FROM_UNIXTIME(e.start), "%H:%i") "time", 
 29 | 			TIME_FORMAT(FROM_UNIXTIME(e.end), "%H:%i") "end_time", 
 30 | 			e.recurrence_rules, 
 31 | 			e.venue "location", 
 32 | 			e.address "formatted_address",
 33 | 			GROUP_CONCAT(CASE WHEN x.taxonomy = "events_tags" THEN REPLACE(t.name, "/", "") ELSE null END SEPARATOR "|") `types`,
 34 | 			p.post_content "notes",
 35 | 			p.post_modified_gmt "updated"
 36 | 		FROM wp_ai1ec_events e
 37 | 		JOIN wp_posts p ON e.post_id = p.ID
 38 | 		JOIN wp_term_relationships r ON p.ID = r.object_id
 39 | 		JOIN wp_term_taxonomy x ON r.term_taxonomy_id = x.term_taxonomy_id
 40 | 		JOIN wp_terms t ON x.term_id = t.term_id
 41 | 		GROUP BY p.ID');
 42 | 
 43 | 		//for appending daily meetings
 44 | 		$daily = array(); 
 45 | 
 46 | 		//days
 47 | 		$days = array('BYday=SU', 'BYday=MO', 'BYday=TU', 'BYday=WE', 'BYday=TH', 'BYday=FR', 'BYday=SA');
 48 | 
 49 | 		//types
 50 | 		$types = array(
 51 | 			'Accessible' => 'X',
 52 | 			'As Bill Sees It' => 'ABSI',
 53 | 			//'Beach Meeting' => 
 54 | 			'Beginner' => 'BE',
 55 | 			'Big Book' => 'BB',
 56 | 			//'Came to Believe' =>
 57 | 			'Closed Meeting' => 'C',
 58 | 			'Crosstalk encouraged' => 'XT',
 59 | 			'Daily Reflections' => 'DR',
 60 | 			'Discussion' => 'D',
 61 | 			'Grapevine' => 'GR',
 62 | 			//'Joe & Charlie' => 
 63 | 			'Literature' => 'LIT',
 64 | 			'Living Sober' => '',
 65 | 			'Meditation' => 'MED',
 66 | 			'Men\'s' => 'M',
 67 | 			'Open Meeting' => 'O',
 68 | 			'Spanish Speaking' => 'S',
 69 | 			'Speaker' => 'SP',
 70 | 			//'Spiritual Meeting' => 
 71 | 			'Step' => 'ST',
 72 | 			'Tradition' => 'T',
 73 | 			//'Varied Format' => 
 74 | 			'Women\'s' => 'W',
 75 | 			'Young People' => 'YP',
 76 | 			//variable
 77 | 		);
 78 | 
 79 | 		for ($i = 0; $i < count($result); $i++) {
 80 | 
 81 | 			//url
 82 | 			$result[$i]->url = 'http://capeatlanticaa.org/ai1ec-event/' . $result[$i]->slug . '/';
 83 | 
 84 | 			//notes
 85 | 			$result[$i]->notes = trim(strip_tags($result[$i]->notes));
 86 | 
 87 | 			//handle types
 88 | 			//$result[$i]->type_compare = $result[$i]->types;
 89 | 			$meeting_types = explode('|', $result[$i]->types);
 90 | 			$result[$i]->types = array();
 91 | 			foreach ($meeting_types as $type) {
 92 | 				if (array_key_exists($type, $types)) {
 93 | 					$result[$i]->types[] = $types[$type];
 94 | 				}
 95 | 			}
 96 | 
 97 | 			//get day from recurrence_rules
 98 | 			if (!empty($result[$i]->recurrence_rules)) {
 99 | 				if ($result[$i]->recurrence_rules == 'FREQ=DAILY;') {
100 | 					unset($result[$i]->recurrence_rules);
101 | 					for ($day = 0; $day < 7; $day++) {
102 | 						$result[$i]->day = $day;
103 | 						$daily[] = clone($result[$i]);
104 | 					}
105 | 				} else {
106 | 					$rules = explode(';', $result[$i]->recurrence_rules);
107 | 					if (isset($rules[2])) {
108 | 						$day = array_search($rules[2], $days);
109 | 						if ($day !== false) {
110 | 							$result[$i]->day = $day;
111 | 							unset($result[$i]->recurrence_rules);
112 | 						}
113 | 					}
114 | 				}
115 | 			}
116 | 		}
117 | 
118 | 		$result = array_merge($result, $daily);
119 | 
120 | 		//dd($daily);
121 | 
122 | 		if (!headers_sent()) header('Access-Control-Allow-Origin: *');
123 | 
124 | 		wp_send_json($result);
125 | 	}
126 | }


--------------------------------------------------------------------------------
/import-scripts/cape-atlantic/readme.txt:
--------------------------------------------------------------------------------
 1 | === Meeting Guide Link ===
 2 | Contributors: meetingguide
 3 | Requires at least: 3.2
 4 | Tested up to: 4.9
 5 | Stable tag: 1.0.0
 6 | 
 7 | This plugin makes a Meeting Guide JSON feed from All-in-One Event Calendar for Cape Atlantic Intergroup
 8 | 
 9 | == Description ==
10 | 
11 | This plugin makes a Meeting Guide JSON feed from All-in-One Event Calendar for Cape Atlantic Intergroup


--------------------------------------------------------------------------------
/import-scripts/charlotte/meeting-guide.cfm:
--------------------------------------------------------------------------------
1 | hi


--------------------------------------------------------------------------------
/import-scripts/georgia/meeting-guide.php:
--------------------------------------------------------------------------------
 1 | getMessage());
17 | }
18 | 
19 | //error handling
20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
21 | 
22 | //select data
23 | try {
24 |   $meetings = $pdo->query('SELECT * FROM mg_meeting_export_V')
25 |     ->fetchAll(PDO::FETCH_ASSOC);
26 | } catch (PDOException $e) {
27 |     die('SQL query failed: ' . $e->getMessage());
28 | }
29 | 
30 | //debug helper
31 | function dd($obj) {
32 |   echo '
';
33 |   print_r($obj);
34 |   exit;
35 | }
36 | 
37 | //make arrays from day and types
38 | $meetings = array_map(function($meeting){
39 |   $meeting['day'] = explode(',', $meeting['day']);
40 |   $meeting['types'] = explode(',', $meeting['types']);
41 |   return $meeting;
42 | }, $meetings);
43 | 
44 | //encode JSON
45 | $meetings = json_encode($meetings);
46 | if (json_last_error()) {
47 |   die('JSON error: ' . json_last_error_msg());
48 | }
49 | 
50 | //make sure headers haven't already been sent, will cause error
51 | if (headers_sent()) {
52 |   die('Error: headers already sent!');
53 | }
54 | 
55 | //output
56 | header('Content-type: application/json; charset=utf-8');
57 | echo $meetings;
58 | 


--------------------------------------------------------------------------------
/import-scripts/las-vegas/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 21 | }
 22 | 
 23 | //error handling
 24 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 25 | 
 26 | $meta_decode = array(
 27 |     '_content_field_20' => 'Sunday',
 28 |     '_content_field_21' => 'Monday',
 29 |     '_content_field_22' => 'Wednesday',
 30 |     '_content_field_23' => 'Tuesday',
 31 |     '_content_field_24' => 'Thursday',
 32 |     '_content_field_25' => 'Friday',
 33 |     '_content_field_26' => 'Saturday',
 34 |     '_content_field_27' => 'notes',
 35 |     '_content_field_28' => 'phone',
 36 |     //'_content_field_29' => 'url',
 37 |     '_content_field_30' => 'email',
 38 |     '_address_line_1' => 'address',
 39 |     '_zip_or_postal_in	dex' => 'postal_code',
 40 | );
 41 | 
 42 | $decode_types = array(
 43 |     '12 X 12 Study' => '12x12',
 44 |     'Big Book Study' => 'B',
 45 |     'Candlelight' => 'CAN',
 46 |     'Childcare Available' => 'BA',
 47 |     'Closed Discussion' => array('C', 'D'),
 48 |     'Gay' => 'G',
 49 |     'Grapevine' => 'GR',
 50 |     'Literature' => 'LIT',
 51 |     'Meditation' => 'MED',
 52 |     'Men\'s Stag' => 'M',
 53 |     'Newcomers' => 'BE',
 54 |     'Open Discussion' => array('O', 'D'),
 55 |     'Secular / Agnostic' => 'A',
 56 |     'Signed Interpreter (Hearing Impaired)' => 'ASL',
 57 |     'Spanish Speaking' => 'S',
 58 |     'Speaker' => 'SP',
 59 |     'Step Study' => 'ST',
 60 |     'Wheelchair Accessible' => 'X',
 61 |     'Women Only' => 'W',
 62 |     'Women\'s meeting' => 'W',
 63 |     'Young People' => 'YP',
 64 | );
 65 | 
 66 | //select data
 67 | try {
 68 | 
 69 |     //get all the meetings
 70 |     $meetings = $pdo->query('SELECT
 71 | 			p.id,
 72 | 			p.post_name,
 73 | 			p.post_title "name",
 74 | 			p.post_modified_gmt "updated"
 75 | 		FROM wp_posts p
 76 | 		WHERE
 77 | 			p.post_type = "w2dc_listing" AND
 78 | 			p.post_status = "publish"')
 79 |         ->fetchAll(PDO::FETCH_ASSOC);
 80 | 
 81 |     //get the metadata
 82 |     $meta = $pdo->query('SELECT
 83 | 			m.post_id,
 84 | 			m.meta_key,
 85 | 			m.meta_value
 86 | 		FROM wp_postmeta m
 87 | 		WHERE
 88 | 			m.post_id IN (SELECT id FROM wp_posts WHERE post_status = "publish" and post_type = "w2dc_listing") AND
 89 | 			m.meta_key IN (' . implode(', ', array_map(function ($key) {return '"' . $key . '"';}, array_keys($meta_decode))) . ')')
 90 |         ->fetchAll(PDO::FETCH_ASSOC);
 91 | 
 92 |     //get the tags
 93 |     $tags = $pdo->query('SELECT
 94 | 			t.name,
 95 | 			x.taxonomy,
 96 | 			r.object_id "post_id"
 97 | 		FROM wp_terms t
 98 | 		JOIN wp_term_taxonomy x ON t.term_id = x.term_id
 99 | 		JOIN wp_term_relationships r ON x.term_taxonomy_id = r.term_taxonomy_id
100 | 		WHERE
101 | 			x.taxonomy IN ("w2dc-category", "w2dc-tag")')
102 |         ->fetchAll(PDO::FETCH_ASSOC);
103 | 
104 | } catch (PDOException $e) {
105 |     die('SQL query failed: ' . $e->getMessage());
106 | }
107 | 
108 | function dd($obj)
109 | {
110 |     echo '
';
111 |     print_r($obj);
112 |     exit;
113 | }
114 | 
115 | function getMetaFor($meeting_id)
116 | {
117 |     global $meta, $meta_decode;
118 |     $values = array_filter($meta, function ($item) use ($meeting_id) {
119 |         return $item['post_id'] == $meeting_id;
120 |     });
121 |     $return = array();
122 |     foreach ($values as $value) {
123 |         $return[$meta_decode[$value['meta_key']]] = $value['meta_value'];
124 |     }
125 |     return $return;
126 | }
127 | 
128 | function getTagsFor($meeting_id)
129 | {
130 |     global $tags;
131 |     $values = array_filter($tags, function ($item) use ($meeting_id) {
132 |         return $item['post_id'] == $meeting_id && $item['taxonomy'] == 'w2dc-category';
133 |     });
134 |     $return = array();
135 |     foreach ($values as $value) {
136 |         if (strtolower($value['name']) == 'noon') {
137 |             $return[] = '12:00 PM';
138 |         } elseif (strtolower($value['name']) == 'midnight') {
139 |             $return[] = '12:00 AM';
140 |         } else {
141 |             $return[] = $value['name'];
142 |         }
143 |     }
144 |     return $return;
145 | }
146 | 
147 | function getLocationName($meeting_id)
148 | {
149 |     global $tags;
150 |     $values = array_filter($tags, function ($item) use ($meeting_id) {
151 |         return ($item['post_id'] == $meeting_id) && ($item['taxonomy'] == 'w2dc-tag');
152 |     });
153 |     if (count($values)) {
154 |         return array_values($values)[0]['name'];
155 |     }
156 | 
157 |     return false;
158 | }
159 | 
160 | //fetch data
161 | $return = array();
162 | foreach ($meetings as $meeting) {
163 | 
164 |     $meeting = array_merge($meeting, getMetaFor($meeting['id']));
165 | 
166 |     //handle joined address
167 |     if (empty($meeting['address'])) {
168 |         continue;
169 |     }
170 | 
171 |     $meeting['address'] = str_replace('
', '
', $meeting['address']); 172 | $meeting['address'] = str_replace('
', '
', $meeting['address']); 173 | $meeting['address'] = explode('
', $meeting['address']); 174 | $address_count = count($meeting['address']); 175 | 176 | $meeting['city'] = null; 177 | 178 | if ($address_count == 1) { 179 | $meeting['address'] = $meeting['address'][0]; 180 | } elseif ($address_count == 2) { 181 | $meeting['city'] = $meeting['address'][1]; 182 | $meeting['address'] = $meeting['address'][0]; 183 | } elseif ($address_count == 3) { 184 | $meeting['location'] = $meeting['address'][0]; 185 | $meeting['city'] = $meeting['address'][2]; 186 | $meeting['address'] = $meeting['address'][1]; 187 | } 188 | 189 | //get location name this way if it's set 190 | if ($location = getLocationName($meeting['id'])) { 191 | $meeting['location'] = $location; 192 | } 193 | 194 | //clean up city 195 | $meeting['city'] = str_replace(', NV', '', $meeting['city']); 196 | $meeting['city'] = str_replace(', Nevada', '', $meeting['city']); 197 | $meeting['city'] = str_replace(', USA', '', $meeting['city']); 198 | $meeting['city'] = str_replace(', United States', '', $meeting['city']); 199 | $meeting['state'] = 'NV'; 200 | $meeting['country'] = 'USA'; 201 | 202 | //address sometimes has the whole thing 203 | if (substr($meeting['address'], -9) == ', NV, USA') { 204 | $meeting['address'] = substr($meeting['address'], 0, -9); 205 | $meeting['address'] = explode(', ', $meeting['address']); 206 | $meeting['city'] = array_pop($meeting['address']); 207 | $meeting['address'] = implode(', ', $meeting['address']); 208 | } 209 | 210 | if (empty($meeting['city'])) { 211 | $meeting['city'] = 'Las Vegas'; 212 | } 213 | 214 | //ad hoc correction 215 | if (strpos($meeting['address'], '101 Pavilion Center') !== false) { 216 | $meeting['address'] = '101 S Pavilion Center Dr'; 217 | $meeting['city'] = 'Las Vegas'; 218 | $meeting['location'] = 'Veterans Memorial Leisure Center'; 219 | } 220 | if (strpos($meeting['address'], '701 Avenue N') !== false) { 221 | $meeting['address'] = '701 Avenue N'; 222 | $meeting['city'] = 'Ely'; 223 | } 224 | if (strpos($meeting['address'], 'McGill Methodist Church') !== false) { 225 | $meeting['location'] = 'McGill Methodist Church'; 226 | $meeting['address'] = '2nd Street & Avenue J'; 227 | $meeting['city'] = 'McGill'; 228 | } 229 | 230 | $meeting['url'] = 'https://www.lvcentraloffice.org/aameetinglisting/' . $meeting['post_name'] . '/'; 231 | 232 | //clean up values 233 | $meeting = array_map('strip_tags', $meeting); 234 | $meeting = array_map('trim', $meeting); 235 | $meeting = array_map(function ($value) { 236 | return empty($value) ? null : $value; 237 | }, $meeting); 238 | 239 | //handle types 240 | $types = getTagsFor($meeting['id']); 241 | $meeting['types'] = array(); 242 | foreach ($types as $type) { 243 | if (array_key_exists($type, $decode_types)) { 244 | if (is_array($decode_types[$type])) { 245 | $meeting['types'] = array_merge($meeting['types'], $decode_types[$type]); 246 | } else { 247 | $meeting['types'][] = $decode_types[$type]; 248 | } 249 | } 250 | } 251 | 252 | //try getting time from types 253 | $meeting['time'] = null; 254 | if ($time = array_filter($types, function ($type) { 255 | return strpos($type, ':') !== false; 256 | })) { 257 | $meeting['time'] = array_values($time)[0]; 258 | } 259 | 260 | /* this is throwing off mcgill meeting, which is "Thurs - 7pm" 261 | //also try getting it from the meeting name 262 | if (strpos($meeting['name'], '-') !== false) { 263 | $name_parts = explode('-', $meeting['name']); 264 | $name_parts = array_map('trim', $name_parts); 265 | foreach ($name_parts as $part) { 266 | if (in_array(substr(strtolower($part), -2), array('am', 'pm'))) { 267 | $meeting['time'] = $part; 268 | $meeting['name'] = implode(' - ', array_diff($name_parts, array($part))); 269 | break; 270 | } 271 | } 272 | } 273 | */ 274 | 275 | //loop through the days 276 | foreach (array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') as $index => $day) { 277 | if (!in_array($day, $types)) { 278 | continue; 279 | } 280 | 281 | if (!empty($meeting[$day])) { 282 | $meeting['day'] = $index; 283 | if (strpos($meeting[$day], '-') === false) { 284 | //sometimes it's all time 285 | if (!$meeting['time'] && strpos($meeting[$day], ':')) { 286 | $meeting['time'] = $meeting[$day]; 287 | } 288 | } else { 289 | //sometimes it's on one side of a dash 290 | $day_parts = explode('-', $meeting[$day]); 291 | $day_parts = array_map('trim', $day_parts); 292 | foreach ($day_parts as $part) { 293 | if (strtolower($part) == 'noon') { 294 | $part = '12:00PM'; 295 | } 296 | 297 | if (strtolower($part) == 'midnight') { 298 | $part = '12:00AM'; 299 | } 300 | 301 | if (!$meeting['time'] && strpos($part, ':') !== false) { 302 | $meeting['time'] = $part; 303 | } 304 | if (array_key_exists($part, $decode_types)) { 305 | if (is_array($decode_types[$part])) { 306 | $meeting['types'] = array_merge($meeting['types'], $decode_types[$part]); 307 | } else { 308 | $meeting['types'][] = $decode_types[$part]; 309 | } 310 | } 311 | } 312 | } 313 | 314 | //format the time 315 | if ($meeting['time']) { 316 | $meeting['time'] = date('H:i', strtotime($meeting['time'])); 317 | } 318 | 319 | //handle the slug 320 | $meeting['slug'] = $meeting['post_name'] . '--' . $meeting['day']; 321 | 322 | $return[] = $meeting; 323 | } 324 | } 325 | } 326 | 327 | //check both open and closed types 328 | $return = array_map(function ($meeting) { 329 | $meeting['types'] = array_unique($meeting['types']); 330 | sort($meeting['types']); 331 | //if both open and closed, remove both 332 | if (in_array('C', $meeting['types']) && in_array('O', $meeting['types'])) { 333 | $meeting['types'] = array_diff($meeting['types'], array('O', 'C')); 334 | } 335 | return $meeting; 336 | }, $return); 337 | 338 | //dd($return); 339 | 340 | //encode JSON 341 | $return = json_encode($return); 342 | if (json_last_error()) { 343 | die('JSON error: ' . json_last_error_msg()); 344 | } 345 | 346 | //make sure headers haven't already been sent, will cause error 347 | if (headers_sent()) { 348 | die('Error: headers already sent!'); 349 | } 350 | 351 | //output 352 | header('Content-type: application/json; charset=utf-8'); 353 | echo $return; 354 | -------------------------------------------------------------------------------- /import-scripts/los-angeles/meeting-guide.php: -------------------------------------------------------------------------------- 1 | getMessage()); 17 | } 18 | 19 | //error handling 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 21 | 22 | //select data 23 | try { 24 | $result = $pdo->query('SELECT * FROM meetings'); 25 | } catch (PDOException $e) { 26 | die('SQL query failed: ' . $e->getMessage()); 27 | } 28 | 29 | //fetch data 30 | $return = array(); 31 | foreach ($result as $row) { 32 | 33 | //trim all values 34 | $row = array_map('trim', $row); 35 | 36 | //types 37 | $types = array(); 38 | if ($row['CLOSED'] == '1') { 39 | $types[] = 'C'; 40 | } else { 41 | $types[] = 'O'; 42 | } 43 | if ($row['MEN'] == '1') $types[] = 'M'; 44 | if ($row['WOMEN'] == '1') $types[] = 'W'; 45 | if ($row['GAY'] == '1') $types[] = 'LGBTQ'; 46 | //if ($row['YOUNG'] == '1') $types[] = 'Y'; 47 | 48 | //build array 49 | $return[] = array( 50 | 'slug' => $row['MEET_NUM'], 51 | 'day' => intval($row['MtgDow']) - 1, 52 | 'name' => $row['Group_Name'], 53 | 'time' => date('H:i', strtotime($row['MtgTime'])), 54 | 'types' => $types, 55 | 'address' => $row['Address'], 56 | 'city' => $row['City'], 57 | 'state' => 'CA', 58 | 'postal_code' => $row['Thomasbros'], 59 | 'country' => 'US', 60 | 'region' => $row['Location'], 61 | ); 62 | } 63 | 64 | 65 | //encode JSON 66 | $return = json_encode($return); 67 | if (json_last_error()) { 68 | die('JSON error: ' . json_last_error_msg()); 69 | } 70 | 71 | //make sure headers haven't already been sent, will cause error 72 | if (headers_sent()) { 73 | die('Error: headers already sent!'); 74 | } 75 | 76 | //output 77 | header('Content-type: application/json; charset=utf-8'); 78 | echo $return; 79 | -------------------------------------------------------------------------------- /import-scripts/low-country/meeting-guide.php: -------------------------------------------------------------------------------- 1 | getMessage()); 17 | } 18 | 19 | //error handling 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 21 | 22 | //select data 23 | try { 24 | $result = $pdo->query('SELECT * FROM data'); 25 | } catch (PDOException $e) { 26 | die('SQL query failed: ' . $e->getMessage()); 27 | } 28 | 29 | function dd($obj) { 30 | echo '
';
31 | 	print_r($obj);
32 | 	exit;
33 | }
34 | 
35 | //fetch data
36 | $return = array();
37 | foreach ($result as $row) {
38 | 
39 | 	//build array
40 | 	$return[] = array(
41 | 		'slug' => $row['id'],
42 | 		'name' => $row['name'],
43 | 		'day' => $row['day'],
44 | 		'time' => $row['time'],
45 | 		'end_time' => $row['end_time'],
46 | 		'types' => explode(' ', $row['types']),
47 | 		'notes' => $row['notes'],
48 | 		'location' => $row['location'],
49 | 		'address' => $row['address'],
50 | 		'city' => $row['city'],
51 | 		'state' => 'SC',
52 | 		'postal_code' => $row['postal_code'],
53 | 		'country' => 'USA',
54 | 		'location_notes' => $row['location_notes'],
55 | 		'region' => $row['region'],
56 | 		'updated' => $row['updated'],
57 | 	);
58 | }
59 | 
60 | 
61 | //encode JSON
62 | $return = json_encode($return);
63 | if (json_last_error()) {
64 | 	die('JSON error: ' . json_last_error_msg());
65 | }
66 | 
67 | //make sure headers haven't already been sent, will cause error
68 | if (headers_sent()) {
69 | 	die('Error: headers already sent!');
70 | }
71 | 
72 | //output
73 | header('Content-type: application/json; charset=utf-8');
74 | echo $return;
75 | 


--------------------------------------------------------------------------------
/import-scripts/nashville/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT 
 25 | 		m.groupid,
 26 | 		m.wkday day,
 27 | 		m.times time,
 28 | 		m.type types,
 29 | 		m.mcomments notes,
 30 | 		GREATEST(m.modified, g.modified) updated,
 31 | 		g.groupname name,
 32 | 		g.address1 location,
 33 | 		g.address2 address,
 34 | 		g.city,
 35 | 		g.state,
 36 | 		g.zip postal_code,
 37 | 		g.comments location_notes
 38 | 	FROM meetings m
 39 | 	JOIN groups g ON m.groupid = g.groupid');
 40 | } catch (PDOException $e) {
 41 |     die('SQL query failed: ' . $e->getMessage());
 42 | }
 43 | 
 44 | $decode_days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 45 | 
 46 | $decode_types = array(
 47 | 	'0D' => array('O', 'D'),
 48 | 	'OD' => array('O', 'D'),
 49 | 	'OD OD' => array('O', 'D'),
 50 | 	'OD  OD' => array('O', 'D'),
 51 | 	'OD CD' => array('C', 'D'),
 52 | 	'OD ALN' => array('D', 'AL-AN'),
 53 | 	'LIT' => 'LIT',
 54 | 	'CD' => 'C',
 55 | 	'WMN' => 'W',
 56 | 	'WMN BEG' => array('W', 'BE'),
 57 | 	'OD AND SEPARATE BEG' => array('O', 'D', 'BE'),
 58 | 	'AND BEG' => 'BE',
 59 | 	'PLUS BEG MEETING' => 'BE',
 60 | 	'PLUS ALN' => 'AL-AN',
 61 | 	'BEG ALN' => array('BE', 'AL-AN'),
 62 | 	'SP' => 'S',
 63 | 	'TT' => 'ST',
 64 | 	'BEG' => 'BE',
 65 | 	'OS' => array('O', 'SP'),
 66 | 	'OS & OD' => array('O', 'SP', 'D'),
 67 | 	'OS-3RD SUNDAY' => array('O', 'SP'),
 68 | 	'BB' => 'B',
 69 | 	'LGBT, ALL WELCOME' => 'LGBTQ',
 70 | 	'CS' => array('C', 'SP'),
 71 | 	'MEN' => 'M',
 72 | 	'MENS' => 'M',
 73 | 	'ALN' => 'AL-AN',
 74 | 	'GV' => 'GR',
 75 | 	'GV ALN' => array('GR', 'AL-AN'),
 76 | 	'BB ALN' => array('B', 'AL-AN'),
 77 | 	'BEG WMN' => array('BE', 'W'),
 78 | 	'LIT ALN' => array('LIT', 'AL-AN'),
 79 | 	'OD ALANON AT 7:30' => array('LIT', 'AL-AN'),
 80 | 	'MEDITATION' => 'MED',
 81 | 	'BD' => array('H'),
 82 | 	'WOMEN' => 'W',
 83 | 	'WMN OD' => array('W', 'O', 'D'),
 84 | 	'11TH STEP' => '11',
 85 | 	'CDLT' => 'CAN',
 86 | 	'BR' => '', //back room
 87 | 	'SS' => 'ST',
 88 | 	'DN' => '', //downstairs
 89 | 	'GAY' => 'G',
 90 | 	'DAILY REFLECTION' => 'DR',
 91 | 	'DAILY REFLECTIONS LT' => 'DR',
 92 | 	'LIVING SOBER' => 'LS',
 93 | 	'GRAPEVINE' => 'GR',
 94 | 	'AS BILL SEES IT' => 'ABSI',
 95 | );
 96 | 
 97 | //fetch data
 98 | $return = array();
 99 | foreach ($result as $row) {
100 | 	
101 | 	//trim all values
102 | 	$row = array_map('trim', $row);
103 | 
104 | 	//format name in title case
105 | 	$name = ucwords(strtolower($row['name']));
106 | 	$name = str_replace('Aa ', 'AA ', $name);
107 | 	$name = str_replace('S.a.s./sober ', 'S.A.S./Sober ', $name);
108 | 
109 | 	//day
110 | 	$row['day'] = array_search($row['day'], $decode_days);
111 | 	
112 | 	//types
113 | 	$types = array();
114 | 	$row['types'] = str_replace('+', ' ', $row['types']);
115 | 	$row['types'] = str_replace('*', '', $row['types']);
116 | 	$row['types'] = str_replace('.', '', $row['types']);
117 | 	$row['types'] = explode('/', $row['types']);
118 | 	foreach ($row['types'] as $type) {
119 | 		$type = trim($type);
120 | 		if (empty($type)) continue;
121 | 		if (!array_key_exists($type, $decode_types)) die($type);
122 | 		if (is_array($decode_types[$type])) {
123 | 			$types = array_merge($types, $decode_types[$type]);
124 | 		} else {
125 | 			$types[] = $decode_types[$type];
126 | 		}
127 | 	}
128 | 
129 | 	//address
130 | 	if (empty($row['address'])) {
131 | 		$row['address'] = $row['location'];
132 | 	}
133 | 
134 | 	//handle time
135 | 	if (strlen($row['time']) == 3) {
136 | 		$row['time'] = substr($row['time'], 0, 1) . ':' . substr($row['time'], 1, 2);
137 | 	} elseif (strlen($row['time']) == 4) {
138 | 		$row['time'] = substr($row['time'], 0, 2) . ':' . substr($row['time'], 2, 2);
139 | 	} else {
140 | 		continue;
141 | 	}
142 | 
143 | 	//build array
144 | 	$return[] = array(
145 | 		'slug' => $row['groupid'] . $row['day'] . $row['time'],
146 | 		'day' => $row['day'],
147 | 		'name' => $name,
148 | 		'time' => $row['time'],
149 | 		'types' => array_unique($types),
150 | 		'location' => $row['location'],
151 | 		'address' => $row['address'],
152 | 		'city' => $row['city'],
153 | 		'state' => $row['state'],
154 | 		'postal_code' => $row['postal_code'],
155 | 		'country' => 'US',
156 | 		'region' => $row['city'],
157 | 		'notes' => $row['notes'],
158 | 		'updated' => date('Y-m-d H:i:s', strtotime($row['updated'])),
159 | 		'location_notes' => $row['location_notes'],
160 | 	);
161 | }
162 | 
163 | 
164 | //encode JSON
165 | $return = json_encode($return);
166 | if (json_last_error()) {
167 | 	die('JSON error: ' . json_last_error_msg());
168 | }
169 | 
170 | //make sure headers haven't already been sent, will cause error
171 | if (headers_sent()) {
172 | 	die('Error: headers already sent!');
173 | }
174 | 
175 | //output
176 | header('Content-type: application/json; charset=utf-8');
177 | echo $return;
178 | 


--------------------------------------------------------------------------------
/import-scripts/nemdaa/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT * FROM meetingsfordisplay');
 25 | } catch (PDOException $e) {
 26 |     die('SQL query failed: ' . $e->getMessage());
 27 | }
 28 | 
 29 | function dd($obj) {
 30 | 	echo '
';
 31 | 	print_r($obj);
 32 | 	exit;
 33 | }
 34 | 
 35 | $type_lookup = array(
 36 | 	'As Bill Sees It' => 'ABSI',
 37 | 	'Beginners' => 'BE',
 38 | 	'Big Book' => 'B',
 39 | 	'Discussion' => 'D',
 40 | 	'Grapevine' => 'GR',
 41 | 	'Speaker' => 'SP',
 42 | 	'Step Study' => 'ST',
 43 | );
 44 | 
 45 | $day_lookup = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 46 | 
 47 | //fetch data
 48 | $return = array();
 49 | foreach ($result as $row) {
 50 | 
 51 | 	$types = array();
 52 | 
 53 | 	if (!empty($row['Open'])) $types[] = 'O';
 54 | 	if (!empty($row['Sex'])) {
 55 | 		if ($row['Sex'] == 'W') {
 56 | 			$types[] = 'W';
 57 | 		} elseif ($row['Sex'] == 'M') {
 58 | 			$types[] = 'M';
 59 | 		}
 60 | 	}
 61 | 	if (!empty($row['Spanish'])) $types[] = 'S';
 62 | 	if (!empty($row['Disability'])) $types[] = 'X';
 63 | 	if (!empty($row['Babysit'])) $types[] = 'BA';
 64 | 	if (!empty($row['Type']) && array_key_exists($row['Type'], $type_lookup)) {
 65 | 		$types[] = $type_lookup[$row['Type']];
 66 | 	}
 67 | 
 68 | 	//build array
 69 | 	$return[] = array(
 70 | 		'slug' => $row['ID'],
 71 | 		'day' => array_search($row['Day'], $day_lookup),
 72 | 		'time' => $row['Time'],
 73 | 		'name' => $row['GroupName'],
 74 | 		'types' => $types,
 75 | 		'location' => $row['Add2'],
 76 | 		'address' => $row['Add1'],
 77 | 		'city' => $row['City'],
 78 | 		'state' => 'MD',
 79 | 		'postal_code' => $row['ZIP'],
 80 | 		'country' => 'US',
 81 | 		'updated' => $row['Updated'],
 82 | 	);
 83 | }
 84 | 
 85 | 
 86 | //encode JSON
 87 | $return = json_encode($return);
 88 | if (json_last_error()) {
 89 | 	die('JSON error: ' . json_last_error_msg());
 90 | }
 91 | 
 92 | //make sure headers haven't already been sent, will cause error
 93 | if (headers_sent()) {
 94 | 	die('Error: headers already sent!');
 95 | }
 96 | 
 97 | //output
 98 | header('Content-type: application/json; charset=utf-8');
 99 | echo $return;
100 | 


--------------------------------------------------------------------------------
/import-scripts/new-hampshire/new-hampshire.php:
--------------------------------------------------------------------------------
 1 |  $string,
56 | 	));
57 | }
58 | 
59 | //function to output json
60 | function output($array) {
61 | 	die(json_encode($array));
62 | }
63 | 


--------------------------------------------------------------------------------
/import-scripts/new-mexico/new-mexico.php:
--------------------------------------------------------------------------------
 1 |  '11',
15 | 	'12' => 'ST',
16 | 	'AB' => 'ABSI',
17 | 	'ABS' => 'ABSI',
18 | 	'ASL' => 'ASL',
19 | 	'B' => 'BE',
20 | 	'BB' => 'BB',
21 | 	'BEG' => 'BE',
22 | 	'BRK' => 'BRK',
23 | 	'BUS' => 'BUS',
24 | 	'C' => 'C',
25 | 	'CC' => 'BA',
26 | 	'D' => 'D',
27 | 	'DR' => 'DR',
28 | 	'FF' => 'FF',
29 | 	'G' => 'G',
30 | 	'GV' => 'GR',
31 | 	'L' => 'L',
32 | 	'LS' => 'LS',
33 | 	'M' => 'M',
34 | 	'MED' => 'MED',
35 | 	'N' => 'N',
36 | 	'NC' => 'NC',
37 | 	'NS' => 'Non-Smoking',
38 | 	'O' => 'O',
39 | 	'S' => 'SP',
40 | 	'SA' => 'SM',
41 | 	'SP' => 'S',
42 | 	'SS' => 'ST',
43 | 	'ST' => 'ST',
44 | 	'TS' => 'TR',
45 | 	'W' => 'W',
46 | 	'WC' => 'X',
47 | 	'YP' => 'Y',
48 | );
49 | 
50 | foreach ($file as &$line) {
51 | 	
52 | 	//split line by delimiter
53 | 	$line = explode('|', $line);
54 | 	
55 | 	//trim all elements
56 | 	$line = array_map('trim', $line);
57 | 
58 | 	//associate with columns	
59 | 	$line = array_combine($columns, $line);
60 | 	
61 | 	//extract 
62 | 	extract($line);
63 | 	
64 | 	//decrement day of week
65 | 	$day--;
66 | 
67 | 
68 | 	//format time
69 | 	$time = date('H:i', strtotime($time));
70 | 	
71 | 	//make address clearer to google
72 | 	$address = str_replace('  ', ' ', $address);
73 | 	if (substr($address, -4) == ', NM') {
74 | 		$address = substr($address, 0, strlen($address) - 4) . ', New Mexico';
75 | 	}
76 | 	
77 | 	//fix two specific issues
78 | 	if ($address == 'San Felipe Pueblo, Uninc Sandoval County, New Mexico') {
79 | 		$address = 'San Felipe Pueblo, New Mexico';
80 | 	} elseif ($address == 'Call DCM') {
81 | 		$address = 'Albuquerque, New Mexico';
82 | 	}
83 | 
84 | 	//types
85 | 	$types = explode(',', $types);
86 | 	$types = array_map('trim', $types);
87 | 	$types = array_intersect_key($decode_types, array_flip($types));
88 | 	$types = array_values($types);
89 | 	
90 | 	$return[] = compact('slug', 'day', 'time', 'name', 'location', 'address', 'region', 'types');
91 | }
92 | 
93 | //send correct mime header
94 | header('Content-type: application/json; charset=utf-8');
95 | 
96 | //output json
97 | echo json_encode($return);


--------------------------------------------------------------------------------
/import-scripts/oklahoma-city/oklahoma_city.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 20 | }
 21 | 
 22 | //error handling
 23 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 24 | 
 25 | //select data
 26 | try {
 27 | 	$result = $pdo->query($sql);
 28 | } catch (PDOException $e) {
 29 |     die('SQL query failed: ' . $e->getMessage());
 30 | }
 31 | 
 32 | //type definitions
 33 | $decode_days = array(
 34 | 	'Sunday' => 0,
 35 | 	'Monday' => 1,
 36 | 	'Tuesday' => 2,
 37 | 	'Wednesday' => 3,
 38 | 	'Thursday' => 4,
 39 | 	'Friday' => 5,
 40 | 	'Saturday' => 6,
 41 | );
 42 | 
 43 | $decode_types = array(
 44 | 	'As Bill Sees It' => 'LIT',	
 45 | 	'Beginners' => 'BE',	
 46 | 	'Big Book' => 'B',	
 47 | 	'Came to Believe' => 'LIT',	
 48 | 	'Daily Reflections' => 'LIT',	
 49 | 	'Discussion' => 'D',	
 50 | 	'Grapevine' => 'GR',	
 51 | 	'Literature' => 'LIT',	
 52 | 	'Living Sober' => 'LIT',	
 53 | 	'Speaker' => 'SP',	
 54 | 	'Step Study' => 'ST',	
 55 | 	'Topic' => 'D',	
 56 | 	'Traditions' => 'TR',	
 57 | );
 58 | 
 59 | //fetch data
 60 | $return = array();
 61 | foreach ($result as $row) {
 62 | 	
 63 | 	//trim all values
 64 | 	$row = array_map('trim', $row);
 65 | 	
 66 | 	//make sure day is valid
 67 | 	if (!array_key_exists($row['Day'], $decode_days)) continue;
 68 | 	
 69 | 	//set types
 70 | 	$types = array();
 71 | 	$types[] = ($row['Open'] == 'Y') ? 'O' : 'C';
 72 | 	if ($row['Smoking'] == 'Y') $types[] = 'SM';
 73 | 	if ($row['Sex'] == 'W') $types[] = 'W';
 74 | 	if ($row['Sex'] == 'M') $types[] = 'M';
 75 | 	if (!empty($row['Spanish'])) $types[] = 'S';
 76 | 	if (!empty($row['Disability'])) $types[] = 'X';
 77 | 	if (!empty($row['Babysit'])) $types[] = 'BA';
 78 | 	sort($types);
 79 | 
 80 | 	//build array
 81 | 	$return[] = array(
 82 | 		'slug' => md5(implode('-', array($row['GroupName'], $row['Day'], $row['Time'], $row['Add1'], implode(',', $types)))),
 83 | 		'day' => $decode_days[$row['Day']],
 84 | 		'name' => $row['GroupName'],
 85 | 		'notes' => $row['Add2'],
 86 | 		'time' => $row['Time'],
 87 | 		'types' => $types,
 88 | 		'address' => $row['Add1'],
 89 | 		'city' => $row['City'],
 90 | 		'state' => 'OK',
 91 | 		'postal_code' => $row['ZIP'],
 92 | 		'region' => $row['City'],
 93 | 	);
 94 | }
 95 | 
 96 | 
 97 | //encode JSON
 98 | $return = json_encode($return);
 99 | if (json_last_error()) {
100 | 	die('JSON error: ' . json_last_error_msg());
101 | }
102 | 
103 | //make sure headers haven't already been sent, will cause error
104 | if (headers_sent()) {
105 | 	die('Error: headers already sent!');
106 | }
107 | 
108 | //output
109 | header('Content-type: application/json; charset=utf-8');
110 | echo $return;
111 | 


--------------------------------------------------------------------------------
/import-scripts/orange-county/meeting-guide.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Title="" Language="C#" AutoEventWireup="true" CodeFile="meeting-guide.aspx.cs" Inherits="JoshMdb2Json" %>
2 | 
4 | 


--------------------------------------------------------------------------------
/import-scripts/orange-county/meeting-guide.aspx.cs:
--------------------------------------------------------------------------------
  1 | using System;
  2 | using System.Linq;
  3 | using System.IO;
  4 | using System.Data;
  5 | using System.Configuration;
  6 | using System.Collections;
  7 | using System.Collections.Generic;
  8 | using System.Globalization;
  9 | using System.Web;
 10 | using System.Text;
 11 | using System.Web.UI;
 12 | using System.Web.UI.WebControls;
 13 | using System.Web.UI.WebControls.WebParts;
 14 | using System.Web.UI.HtmlControls;
 15 | using System.Web.Security;
 16 | using System.Security.Cryptography; 
 17 | 
 18 | public partial class JoshMdb2Json : System.Web.UI.Page
 19 | {
 20 |     protected void Page_Load(object sender, EventArgs e)
 21 |     {      
 22 |         GetJsonFromMdb();    // do the work
 23 |     }
 24 | 
 25 |     public static string GetMd5Hash(MD5 md5Hash, string input)
 26 |     {
 27 |         // Convert the input string to a byte array and compute the hash.
 28 |         byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
 29 |         // Create Stringbuilder var to collect bytes and create a hash string.
 30 |         StringBuilder sBuilder = new StringBuilder();
 31 |         // Loop through each byte of hashed data, format each as hex string.
 32 |         for (int i = 0; i < data.Length; i++)
 33 |         {
 34 |             sBuilder.Append(data[i].ToString("x2"));
 35 |         }
 36 |         return sBuilder.ToString();         // Return hex string.
 37 |     }
 38 | 
 39 |     protected void GetJsonFromMdb()
 40 |     {
 41 |         TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
 42 |         string mtgDay;
 43 |         string mtgTime;
 44 |         string mtgCity;
 45 |         string mtgName;
 46 |         string mtgAddr;
 47 |         string mtgZip;
 48 |         string mtgDOU;
 49 |         string mtgADA;
 50 |         string mtgTypes;
 51 |         string mtgNotes;
 52 |         string hashSrc;
 53 |         string hashOut;
 54 |         MD5 md5Hash = MD5.Create();
 55 |         dsJson.DataBind();
 56 |         DataView dV = (DataView)dsJson.Select(DataSourceSelectArguments.Empty);
 57 |         DataTable dT;
 58 |         dT = dV.ToTable();
 59 |         StringBuilder jsonString = new StringBuilder();
 60 |         jsonString.Append("[");
 61 |         bool flgError = false;
 62 |         int errCount = 0;
 63 |         for (int i = 0; i < dT.Rows.Count; i++)
 64 |         {
 65 |             flgError = false;
 66 |             int mtgDayN = 0;
 67 |             mtgDay = dT.Rows[i]["mtgday"].ToString();
 68 |             if (int.TryParse(mtgDay, out mtgDayN))
 69 |             {
 70 |                 if (mtgDayN == 0)
 71 |                 {
 72 |                     flgError = true;
 73 |                 }
 74 |                 else
 75 |                 {
 76 |                     mtgDayN = mtgDayN - 1;
 77 |                     mtgDay = mtgDayN.ToString();
 78 |                 }
 79 |             }
 80 |             else
 81 |             {
 82 |                 flgError = true;
 83 |             }
 84 |             mtgTime = dT.Rows[i]["Time"].ToString().Substring(11, 5);
 85 |             if (mtgTime.Substring(mtgTime.Length - 1) == ":")
 86 |             { // kludge to fix time data error
 87 |                 mtgTime = mtgTime.Substring(0, mtgTime.Length - 1);
 88 |             }
 89 |             string strHH = mtgTime.Substring(0, mtgTime.IndexOf(":"));
 90 |             string strMM = mtgTime.Substring(mtgTime.IndexOf(":") + 1);
 91 |             int mtgHH = 0;
 92 |             int mtgMM = 0;
 93 |             if (int.TryParse(strHH, out mtgHH))
 94 |             {
 95 |                 if (mtgHH > 23)
 96 |                 {
 97 |                     flgError = true;
 98 |                 }
 99 |             }
100 |             else
101 |             {
102 |                 flgError = true;
103 |             }
104 |             if (int.TryParse(strMM, out mtgMM))
105 |             {
106 |                 if (mtgMM > 59)
107 |                 {
108 |                     flgError = true;
109 |                 }
110 |             }
111 |             else
112 |             {
113 |                 flgError = true;
114 |             }
115 |             mtgCity = dT.Rows[i]["City"].ToString();
116 |             mtgName = dT.Rows[i]["mtgname"].ToString().Replace("\"", "\\\"");
117 |             mtgName = mtgName.Replace("'s", "'S");
118 |             mtgAddr = dT.Rows[i]["mtgaddress"].ToString();
119 |             mtgNotes = "";
120 |             if (mtgAddr.ToLower().IndexOf("suite") > -1)  // Per Josh, massage address
121 |             {  // strip suite+ from address after adding suite+ data to notes field
122 |                 mtgNotes = mtgAddr.Substring(mtgAddr.ToLower().IndexOf("suite"));
123 |                 mtgAddr = mtgAddr.Substring(0, mtgAddr.ToLower().IndexOf("suite"));
124 |             }
125 |             hashSrc = mtgDay + mtgTime + mtgCity + mtgName + mtgAddr;
126 |             hashOut = GetMd5Hash(md5Hash, hashSrc);
127 |             mtgZip = dT.Rows[i]["PostalCode"].ToString();
128 |             mtgDOU = dT.Rows[i]["mtgDou"].ToString();
129 |             mtgADA = dT.Rows[i]["mtgADA"].ToString();
130 |             mtgTypes = dT.Rows[i]["typecodes"].ToString();
131 |             if (mtgTypes.Substring(0, 1) != "(" || mtgTypes.Substring(mtgTypes.Length - 1, 1) != ")")
132 |             {
133 |                 flgError = true;
134 |             }
135 |             else
136 |             {
137 |                 mtgTypes = "[" + mtgTypes + "]";
138 |                 mtgTypes = mtgTypes.Replace("(", "|");
139 |                 mtgTypes = mtgTypes.Replace(")", "|");
140 |                 mtgTypes = mtgTypes.Replace("~", "S");
141 |                 mtgTypes = mtgTypes.Replace("GA", "G");
142 |                 mtgTypes = mtgTypes.Replace(",", "|,|");
143 |                 mtgTypes = mtgTypes.Replace("|", "\"");
144 |             }
145 |             if (flgError == false) // build a JSON feed entry
146 |             {
147 |                 jsonString.Append("{\"slug\":\"" + hashOut + "\",");
148 |                 jsonString.Append("\"day\":\"" + mtgDay + "\",");
149 |                 jsonString.Append("\"name\":\"" + ti.ToTitleCase(mtgName).Replace("'s", "'S") + "\",");
150 |                 //           jsonString.Append("\"slug\":\"" + dT.Rows[i]["slug"].ToString() + "\",");
151 |                 //               if (dT.Rows[i]["grp"].ToString().Length < 1)
152 |                 //               {
153 |                 //            jsonString.Append("\"group\":\"" + mtgName + "\",");
154 |                 //                }
155 |                 //                else
156 |                 //                {
157 |                 //                    jsonString.Append("\"group\":\"" + dT.Rows[i]["grp"].ToString() + "\",");
158 |                 //                }
159 |                 jsonString.Append("\"" + "time" + "\":\"" + mtgTime + "\",");
160 |                 //                if (Utilities.IsValidDate(dT.Rows[i]["end_time"].ToString()) == true)
161 |                 //                {
162 |                 //                    jsonString.Append("\"" + "end_time" + "\":\"" + dT.Rows[i]["end_time"].ToString() + "\",");
163 |                 //                }
164 |                 //                else
165 |                 //                {
166 |                 //                }
167 |                 //                if (dT.Rows[i]["location"].ToString().Length < 1)
168 |                 //                {
169 |                 //                    jsonString.Append("\"" + "location" + "\":\"\",");
170 |                 //                }
171 |                 //                else
172 |                 //                {
173 |                 //                    jsonString.Append("\"" + "location" + "\":\"" + dT.Rows[i]["location"].ToString() + "\",");
174 |                 //                }
175 |                 jsonString.Append("\"" + "address" + "\":\"" + mtgAddr);
176 |                 // append zip code to address, if one exists
177 |                 if (mtgZip.Length > 1)
178 |                 {
179 |                     jsonString.Append(" " + mtgZip);
180 |                 }
181 |                 jsonString.Append("\",");                
182 |                 jsonString.Append("\"" + "types" + "\":" + mtgTypes + ",");
183 |                 
184 |                 //              if (dT.Rows[i]["website"].ToString().IndexOf(".") > 0)
185 |                 //              {
186 |                 //                  if (dT.Rows[i]["website"].ToString().IndexOf("http:") < 0)
187 |                 //                  {
188 |                 //                      jsonString.Append("\"website\":\"http:\\/\\/" + dT.Rows[i]["website"].ToString().Replace("/", "\\/") + "\",");
189 |                 //                  }
190 |                 //                  else
191 |                 //                  {
192 |                 //                      jsonString.Append("\"website\":\"" + dT.Rows[i]["website"].ToString().Replace("/", "\\/") + "\",");
193 |                 //                  }
194 |                 //              }
195 |                 //              else
196 |                 //              {
197 |                 //                  jsonString.Append("\"website\":\"\",");
198 |                 //              }
199 |                 //              if (dT.Rows[i]["url"].ToString().IndexOf(".") > 0)
200 |                 //              {
201 |                 //                  if (dT.Rows[i]["url"].ToString().IndexOf("http:") < 0)
202 |                 //                  {
203 |                 //                      jsonString.Append("\"url\":\"http:\\/\\/" + dT.Rows[i]["url"].ToString().Replace("/", "\\/") + "\",");
204 |                 //                  }
205 |                 //                  else
206 |                 //                  {
207 |                 //                      jsonString.Append("\"url\":\"" + dT.Rows[i]["url"].ToString().Replace("/", "\\/") + "\",");
208 |                 //                  }
209 |                 //              }
210 |                 //              else
211 |                 //              {
212 |                 //                  string qsStr = "http://" + "tbs";
213 |                 //                  jsonString.Append("\"url\":\"" + qsStr + "\",");
214 |                 //              }
215 |                 //              if (dT.Rows[i]["MeetingImage"].ToString().IndexOf(".") > 0)
216 |                 //              {
217 |                 //                  if (dT.Rows[i]["MeetingImage"].ToString().IndexOf("http:") < 0)
218 |                 //                  {
219 |                 //                      jsonString.Append("\"image\":\"http:\\/\\/" + AAGroupSiteConfiguration.DomainURL + "\\/" + dT.Rows[i]["MeetingImage"].ToString().Replace("/", "\\/") + "\",");
220 |                 //                  }
221 |                 //                  else
222 |                 //                  {
223 |                 //                      jsonString.Append("\"image\":\"" + dT.Rows[i]["MeetingImage"].ToString().Replace("/", "\\/") + "\",");
224 |                 //                  }
225 |                 //              }
226 |                 //              else
227 |                 //                {
228 |                 //                    jsonString.Append("\"image\":\"\",");
229 |                 //                }
230 |                 jsonString.Append("\"notes\":\"" + mtgNotes.Replace("\"", "") + "\",");
231 |                 // LAST JSON ELEMENT -- OMIT TRAILING COMMA from StringBuilder str
232 |                 jsonString.Append("\"updated\":\"" + mtgDOU.Replace("\"", "") + "\"");
233 |                 jsonString.Append("},");
234 |             }
235 |             else
236 |             {
237 |                 errCount = errCount + 1;
238 |             }
239 |         }
240 |         jsonString.Remove(jsonString.Length - 1, 1); // remove last trailing comma
241 |         jsonString.Append("]"); // enclose json with closing bracket
242 | 		Response.AddHeader("Content-type", "text/json");
243 | 		Response.Write(jsonString.ToString()); // write to browser
244 |     }
245 | }
246 | 


--------------------------------------------------------------------------------
/import-scripts/orange-county/meeting-guide.php:
--------------------------------------------------------------------------------
  1 |  'C',
 26 | 	'O' => 'O',
 27 | 	'Y' => 'Y',
 28 | 	'~' => 'S',
 29 | 	'W' => 'W',
 30 | 	'M' => 'M',
 31 | 	'GA' => 'G',
 32 | 	'CC' => 'BA',
 33 | 	'BG' => 'BE',
 34 | 	'TA' => 'MED',
 35 | 	'SP' => 'SP',
 36 | );
 37 | 
 38 | $result = odbc_exec($connection, 'SELECT
 39 | 		DK AS day,
 40 | 		city,
 41 | 		time,
 42 | 		TYPE AS types,
 43 | 		[MEETING NAME] AS [name],
 44 | 		address,
 45 | 		ZIP AS postal_code,
 46 | 		[LAST CHANGE] AS updated,
 47 | 		[Hndcpd Eqpd] AS handicapped
 48 | 	FROM [JAN99_981213]
 49 | 	WHERE [address] IS NOT NULL');
 50 | 
 51 | $meetings = $slugs = array();
 52 | 
 53 | while ($row = odbc_fetch_array($result)) { 
 54 | 
 55 | 	//decrement day by one
 56 | 	$row['day'] = $row['day'] - 1;
 57 | 
 58 | 	//format time
 59 | 	$row['time'] = substr($row['time'], 11, 5);
 60 | 
 61 | 	//explode and trim
 62 | 	$types = array_map('trim', explode(',', trim($row['types'], ' ()')));
 63 | 
 64 | 	$row['types'] = $row['handicapped'] ? array('X') : array();
 65 | 	unset($row['handicapped']);
 66 | 
 67 | 	foreach ($types as $type) {
 68 | 		if (array_key_exists($type, $decode_types)) {
 69 | 			$row['types'][] = $decode_types[$type];
 70 | 		}
 71 | 	}
 72 | 
 73 | 	//title case name
 74 | 	$row['name'] = ucwords(strtolower($row['name']));
 75 | 	$row['name'] = str_replace('Aa', 'AA', $row['name']);
 76 | 	$row['name'] = str_replace('Dp ', 'DP ', $row['name']);
 77 | 
 78 | 	//title case city
 79 | 	$row['city'] = ucwords(strtolower($row['city']));
 80 | 	$row['region'] = $row['city'];
 81 | 
 82 | 	//extra information for geocoder
 83 | 	$row['state'] = 'CA';
 84 | 	$row['country'] = 'USA';
 85 | 
 86 | 	//create a quasi-unique slug from day, time, city, name, and address
 87 | 	$row['slug'] = md5(serialize(array($row['day'], $row['time'], $row['city'], $row['name'], $row['address'])));
 88 | 	$slugs[] = $row['slug'];
 89 | 
 90 | 	//parse extra stuff from address
 91 | 	foreach ($delimiters as $delimiter) {
 92 | 		$pos = stripos($row['address'], $delimiter);
 93 | 		if ($pos !== false) {
 94 | 			$row['notes'] = substr($row['address'], $pos + 1);
 95 | 			$row['address'] = substr($row['address'], 0, $pos);
 96 | 		}
 97 | 	}
 98 | 
 99 | 	//handle special cases
100 | 	if (($row['name'] == 'Right Start') && in_array($row['city'], array('Placentia', 'Yorba Linda'))) {
101 | 		continue; //added after
102 | 	}
103 | 
104 | 	$meetings[] = $row;
105 | }
106 | 
107 | odbc_close($connection);
108 | 
109 | //add 'right start' meeting
110 | if ((date('n') > 4) && (date('n') < 10)) {
111 | 	$meetings[] = array(
112 | 		'day' => 0,
113 | 		'time' => '08:30',
114 | 		'name' => 'Right Start',
115 | 		'city' => 'Placentia',
116 | 		'region' => 'Placentia',
117 | 		'state' => 'CA',
118 | 		'country' => 'USA',
119 | 		'address' => '1200 Carlsbad St.',
120 | 		'location' => 'Los Vaqueros Park',
121 | 		'notes' => 'October - April at 19045 E. Yorba Linda Bl., Yorba Linda, CA (Congregation Beth Meir Synagogue), May - September at Los Vaqueros Park @ 1200 Carlsbad St.',
122 | 	);
123 | } else {
124 | 	$meetings[] = array(
125 | 		'day' => 0,
126 | 		'time' => '08:30',
127 | 		'name' => 'Right Start',
128 | 		'city' => 'Yorba Linda',
129 | 		'region' => 'Yorba Linda',
130 | 		'state' => 'CA',
131 | 		'country' => 'USA',
132 | 		'address' => '19045 E. Yorba Linda Bl.',
133 | 		'location' => 'Congregation Beth Meir Synagogue',
134 | 		'notes' => 'October - April at 19045 E. Yorba Linda Bl., Yorba Linda, CA (Congregation Beth Meir Synagogue), May - September at Los Vaqueros Park @ 1200 Carlsbad St.',
135 | 	);
136 | }
137 | 
138 | if (!headers_sent()) {
139 | 	header('Content-type: application/json; charset=utf-8');
140 | }
141 | 
142 | echo json_encode($meetings);
143 | 
144 | //debugging
145 | function dd($content) {
146 | 	echo '
';
147 | 	print_r($content);
148 | 	exit;
149 | }


--------------------------------------------------------------------------------
/import-scripts/ottawa/meeting-guide-json.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 25 | 
 26 | }
 27 | 
 28 | //error handling
 29 | 
 30 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 31 | 
 32 | 
 33 | //select data
 34 | 
 35 | try {
 36 | 
 37 | 	$result = $pdo->query('SELECT * FROM meetings');
 38 | 
 39 | } catch (PDOException $e) {
 40 | 
 41 |     die('SQL query failed: ' . $e->getMessage());
 42 | 
 43 | }
 44 | 
 45 | 
 46 | 
 47 | //debugging
 48 | 
 49 | function dd($obj) {
 50 | 	echo '
';
 51 | 	print_r($obj);
 52 | 	exit;
 53 | }
 54 | 
 55 | //fetch data into array
 56 | $return = array();
 57 | foreach ($result as $row) {
 58 | 	
 59 | 	//assemble types & notes fields
 60 | 	$types = $notes = array();
 61 | 	
 62 | 	//notes
 63 | 	if (!empty($row['announcementNotes'])) $notes[] = $row['announcementNotes'];
 64 | 	if (!empty($row['locationNotes'])) $notes[] = $row['locationNotes'];
 65 | 	if (!empty($row['businessMeeting'])) $notes[] = $row['businessMeeting'];
 66 | 	
 67 | 	//types
 68 | 	if ($row['language'] == 'Spanish') $types[] = 'S';
 69 | 	if ($row['language'] == 'French') $types[] = 'FR';
 70 | 	if (!empty($row['typeClosed'])) {
 71 | 		$types[] = 'C';
 72 | 	} elseif (!empty($row['typeOpen'])) {
 73 | 		$types[] = 'O';
 74 | 	}
 75 | 	if (!empty($row['accessibility'])) $types[] = 'X';
 76 | 	if (!empty($row['typeDiscussion'])) $types[] = 'D';
 77 | 	if (!empty($row['typeSpeaker'])) $types[] = 'SP';
 78 | 	if (!empty($row['typeMeditation'])) $types[] = 'MED';
 79 | 	if ($row['typeSpecial'] == 'WO') {
 80 | 		$types[] = 'W';
 81 | 	} elseif ($row['typeSpecial'] == 'LGBT') {
 82 | 		$types[] = 'LGBTQ';
 83 | 	} elseif ($row['typeSpecial'] == 'MO') {
 84 | 		$types[] = 'M';
 85 | 	} elseif ($row['typeSpecial'] == 'STEP') {
 86 | 		$types[] = 'ST';
 87 | 	}
 88 | 	if ($row['typeNotes'] == 'BB') {
 89 | 		$types[] = 'B';
 90 | 	} elseif ($row['typeNotes'] == 'TR') {
 91 | 		$types[] = 'TR';
 92 | 	} elseif ($row['typeNotes'] == 'MO') {
 93 | 		$types[] = 'M';
 94 | 	} elseif ($row['typeNotes'] == 'STEP') {
 95 | 		$types[] = 'ST';
 96 | 	}
 97 | 	$types = array_unique($types);
 98 | 	
 99 | 	$return[] = array(
100 | 		'name' => $row['groupName'],
101 | 		'slug' => $row['meetingId'],
102 | 		'day' => $row['dayNumber'] - 1,
103 | 		'time' => $row['meetingTime'],
104 | 		'location' => $row['landmark'],
105 | 		'group' => $row['groupName'],
106 | 		'notes' => implode(PHP_EOL, $notes),
107 | 		'updated' => date('Y-m-d H:m:s'),
108 | 		'url' => null,
109 | 		'types' => $types,
110 | 		'address' => $row['location'],
111 | 		'city' => $row['city'],
112 | 		'state' => null,
113 | 		'postal_code' => null,
114 | 		'country' => 'CA',
115 | 		'region' => $row['area'],
116 | 		'latitude' => $row['latitude'],
117 | 		'longitude' => $row['longitude'],
118 | 	);
119 | }
120 | 
121 | 
122 | //return JSON
123 | $return = json_encode($return);
124 | if (json_last_error()) error(json_last_error_msg());
125 | die($return);
126 | 
127 | //function to handle errors
128 | function error($string) {
129 | 	output(array(
130 | 		'error' => $string,
131 | 	));
132 | }


--------------------------------------------------------------------------------
/import-scripts/phoenix/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT * FROM wp_SRI_MEETINGS');
 25 | } catch (PDOException $e) {
 26 |     die('SQL query failed: ' . $e->getMessage());
 27 | }
 28 | 
 29 | function dd($obj) {
 30 | 	echo '
';
 31 | 	print_r($obj);
 32 | 	exit;
 33 | }
 34 | 
 35 | /*
 36 | CODES:
 37 | [O]=Open;
 38 | [C]=Closed;
 39 | [BB]=Big Book;
 40 | [BG]=Newcomer's;
 41 | [GL]=Gay-Lesbian;
 42 | [SF]=Senior-Friendly;
 43 | [YP]=Young People;
 44 | [M]=Men;
 45 | [W]=Women;
 46 | [K]=Smoking OK;
 47 | [NA]=Native American;
 48 | [D]=Discussion;
 49 | [S]=Speaker;
 50 | [T]=Step Study;
 51 | [X]=12+12 Study;
 52 | [%]=Wheelchair Access
 53 | */
 54 | 
 55 | $type_lookup = array(
 56 | 	'O' => 'O',
 57 | 	'C' => 'C',
 58 | 	'BB' => 'BB',
 59 | 	'BG' => 'BE',
 60 | 	'GL' => 'LGBTQ',
 61 | 	'SF' => 'SF',
 62 | 	'YP' => 'Y',
 63 | 	'M' => 'M',
 64 | 	'W' => 'W',
 65 | 	'K' => 'SM',
 66 | 	'NA' => 'N',
 67 | 	'D' => 'D',
 68 | 	'S' => 'SP',
 69 | 	'T' => 'ST',
 70 | 	'X' => '12x12',
 71 | 	'%' => 'X',
 72 | );
 73 | 
 74 | $day_lookup = array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT');
 75 | 
 76 | $separators = array('STE', 'SUITE', '#');
 77 | 
 78 | //fetch data
 79 | $return = array();
 80 | foreach ($result as $row) {
 81 | 
 82 | 	//split the types on a space and look them up
 83 | 	$types = array_map(function($key) use ($type_lookup) {
 84 | 		return @$type_lookup[$key];
 85 | 	}, explode(' ', $row['accomodations']));
 86 | 
 87 | 	//see if it's spanish
 88 | 	if (stristr($row['notes'], 'spanish')) {
 89 | 		$types[] = 'S';
 90 | 	}
 91 | 
 92 | 	//move any suite or room numbers to the notes for proper geocoding
 93 | 	foreach ($separators as $separator) {
 94 | 		if ($start = strpos($row['address'], $separator)) {
 95 | 			$row['notes'] = substr($row['address'], $start) . "\n" . $row['notes'];
 96 | 			$row['address'] = trim(substr($row['address'], 0, $start));
 97 | 		}
 98 | 	}
 99 | 
100 | 	//build array
101 | 	$return[] = array(
102 | 		'slug' => $row['id'],
103 | 		'day' => array_search($row['weekday'], $day_lookup),
104 | 		'time' => $row['time_of_day'],
105 | 		'name' => $row['title'],
106 | 		'types' => $types,
107 | 		'address' => $row['address'],
108 | 		'city' => $row['city'],
109 | 		'postal_code' => $row['zip_code'],
110 | 		'country' => 'US',
111 | 		'notes' => $row['notes'],
112 | 	);
113 | }
114 | 
115 | 
116 | //encode JSON
117 | $return = json_encode($return);
118 | if (json_last_error()) {
119 | 	die('JSON error: ' . json_last_error_msg());
120 | }
121 | 
122 | //make sure headers haven't already been sent, will cause error
123 | if (headers_sent()) {
124 | 	die('Error: headers already sent!');
125 | }
126 | 
127 | //output
128 | header('Content-type: application/json; charset=utf-8');
129 | echo $return;
130 | 


--------------------------------------------------------------------------------
/import-scripts/pittsburgh/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT * FROM meetings');
 25 | } catch (PDOException $e) {
 26 |     die('SQL query failed: ' . $e->getMessage());
 27 | }
 28 | 
 29 | function dd($obj) {
 30 | 	echo '
';
 31 | 	print_r($obj);
 32 | 	exit;
 33 | }
 34 | 
 35 | $day_lookup = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 36 | 
 37 | 
 38 | //fetch data
 39 | $return = array();
 40 | foreach ($result as $row) {
 41 | 
 42 | 	//format time
 43 | 	$time = str_pad($row['MTGTIME'], 4, '0', STR_PAD_LEFT);
 44 | 
 45 | 	//prepare types
 46 | 	$types = array();
 47 | 	if (stristr($row['TYPE1'], 'closed')) {
 48 | 		$types[] = 'C';
 49 | 	} elseif (stristr($row['TYPE1'], 'open')) {
 50 | 		$types[] = 'O';
 51 | 	}
 52 | 	if (stristr($row['TYPE1'], 'discussion')) $types[] = 'D';
 53 | 	if (stristr($row['TYPE1'], '12&12')) $types[] = '12x12';
 54 | 	if (stristr($row['TYPE1'], 'as bill sees it')) $types[] = 'ABSI';
 55 | 	if (stristr($row['TYPE1'], 'beginner')) $types[] = 'BE';
 56 | 	if (stristr($row['TYPE1'], 'big book')) $types[] = 'BB';
 57 | 	if (stristr($row['TYPE1'], 'speaker')) $types[] = 'SP';
 58 | 	if (stristr($row['TYPE1'], 'step')) $types[] = 'ST';
 59 | 	if (stristr($row['TYPE1'], 'tradition')) $types[] = 'T';
 60 | 	if (stristr($row['TYPE1'], 'women') || $row['ATTR3'] == 'Women' || stristr($row['MTGNAME'], 'women')) {
 61 | 		$types[] = 'W';
 62 | 	} elseif (stristr($row['TYPE1'], 'men') || $row['ATTR3'] == 'Men' || stristr($row['TYPE1'], 'men`s')) {
 63 | 		$types[] = 'M';
 64 | 	}
 65 | 	if (stristr($row['ATTR3'], 'young people')) $types[] = 'Y';
 66 | 	if (stristr($row['ATTR2'], 'american indian') || stristr($row['ATTR3'], 'american indian')) $types[] = 'N';
 67 | 	if (stristr($row['ATTR2'], 'accessible')) $types[] = 'X';
 68 | 	if (stristr($row['ATTR2'], 'babysitting')) $types[] = 'BA';
 69 | 	if (stristr($row['ATTR2'], 'freethinkers')) $types[] = 'A';
 70 | 
 71 | 	//prepare notes
 72 | 	$notes = [];
 73 | 	if ($row['TYPE2']) $notes[] = $row['TYPE2'];
 74 | 	if ($row['TYPE3']) $notes[] = $row['TYPE3'];
 75 | 	if ($row['ADDR2']) $notes[] = $row['ADDR2'];
 76 | 	if ($row['ADDR3']) $notes[] = $row['ADDR3'];
 77 | 
 78 | 	//build array
 79 | 	$return[] = array(
 80 | 		'slug' => $row['SLUG'],
 81 | 		'day' => array_search($row['MTGDAY'], $day_lookup),
 82 | 		'time' => substr($time, 0, 2) . ':' . substr($time, 2, 2),
 83 | 		'name' => $row['MTGNAME'],
 84 | 		'types' => $types,
 85 | 		'location' => $row['MTGLOC'],
 86 | 		'address' => $row['ADDR1'],
 87 | 		'city' => $row['MTGAREA'],
 88 | 		'postal_code' => $row['ZIP'],
 89 | 		'country' => 'US',
 90 | 		'notes' => trim(implode("\n", $notes)),
 91 | 		'updated' => $row['UPDATED'],
 92 | 	);
 93 | }
 94 | 
 95 | 
 96 | //encode JSON
 97 | $return = json_encode($return);
 98 | if (json_last_error()) {
 99 | 	die('JSON error: ' . json_last_error_msg());
100 | }
101 | 
102 | //make sure headers haven't already been sent, will cause error
103 | if (headers_sent()) {
104 | 	die('Error: headers already sent!');
105 | }
106 | 
107 | //output
108 | header('Content-type: application/json; charset=utf-8');
109 | echo $return;
110 | 


--------------------------------------------------------------------------------
/import-scripts/puget-sound/datatojson.py:
--------------------------------------------------------------------------------
  1 | import requests
  2 | import simplejson as json
  3 | 
  4 | def meetingdata():
  5 | 	#This script is run as a simple Flask app on a free Heroku plan to allow meeting data in a Google Sheet to connect to the Meeting Guide app
  6 | 	#For full Flask app see https://github.com/pugetsoundaa/jsonfeed
  7 | 
  8 | 	#Google Sheet for Puget Sound AA CSO: https://docs.google.com/spreadsheets/d/1fLxXxKFIiuPJOuTTNzAn1S0rmgjRQhFxqDNZabACIcI/edit?usp=sharing
  9 | 	#Google Sheet ID from publicly shared link above
 10 | 	SPREADSHEET_ID = '1fLxXxKFIiuPJOuTTNzAn1S0rmgjRQhFxqDNZabACIcI'
 11 | 	#Google Sheet JSON Feed URL - must have published the spreadsheet to the web (different than sharing, File->Publish to the web...)
 12 | 	SPREADSHEET_FEED_URL = "https://spreadsheets.google.com/feeds/list/"+SPREADSHEET_ID+"/1/public/values?alt=json"
 13 | 
 14 | 	#Requests JSON and then parses it into a Python object
 15 | 	json_request = requests.get(SPREADSHEET_FEED_URL)
 16 | 	json_string = json_request.text
 17 | 	parsed_json = json.loads(json_string)
 18 | 	#Preprocessing before meeting loop
 19 | 	gs_meetings = parsed_json["feed"]["entry"]
 20 | 	gs_meetings_num = len(gs_meetings)
 21 | 	output = []
 22 | 
 23 | 	#Loop to create array of meetings, each as a dictionary
 24 | 	for x in range (0, gs_meetings_num):
 25 | 		single_meeting_dict = {}
 26 | 		single_meeting_dict.update({'name' : gs_meetings[x]["gsx$name"]["$t"]})
 27 | 		single_meeting_dict.update({'slug' : gs_meetings[x]["gsx$slug"]["$t"]})
 28 | 		single_meeting_dict.update({'day' : dayArray(gs_meetings[x])})
 29 | 		single_meeting_dict.update({'time' : timeFormatted(gs_meetings[x])})
 30 | 		single_meeting_dict.update({'location' : gs_meetings[x]["gsx$location"]["$t"]})
 31 | 		single_meeting_dict.update({'notes' : gs_meetings[x]["gsx$websitenotes"]["$t"]})
 32 | 		single_meeting_dict.update({'updated' : updatedFormatted(gs_meetings[x])})
 33 | 		single_meeting_dict.update({'types' : typesArray(gs_meetings[x])})
 34 | 		single_meeting_dict.update({'address' : gs_meetings[x]["gsx$address"]["$t"]})
 35 | 		single_meeting_dict.update({'city' : gs_meetings[x]["gsx$city"]["$t"]})
 36 | 		single_meeting_dict.update({'state' : 'WA'})
 37 | 		single_meeting_dict.update({'postal_code' : gs_meetings[x]["gsx$zipcode"]["$t"]})
 38 | 		single_meeting_dict.update({'country' : 'US'})
 39 | 		output.append(single_meeting_dict)
 40 | 
 41 | 	return output
 42 | 
 43 | 
 44 | #properly formats updated into YYYY-MM-DD HH:MM:SS
 45 | def updatedFormatted(meeting):
 46 | 	lupdateString = meeting["gsx$updated"]["$t"]
 47 | 	updatedoutput = []
 48 | 	
 49 | 	#checks to see if the month AND day are single digits
 50 | 	if(len(lupdateString) == 8):
 51 | 		#insert 0 in front of month
 52 | 		lupdateString = "0" + lupdateString
 53 | 	#checks to see if the month OR day is a single digit
 54 | 	if(len(lupdateString) == 9):
 55 | 		#checks to see if month is double digit and if yes inserts 0 in front of day
 56 | 		if(lupdateString[2] == "/"):
 57 | 			lupdateString = lupdateString[:3] + "0" + lupdateString[3:]
 58 | 		else:
 59 | 			#insert 0 in front of month
 60 | 			lupdateString = "0" + lupdateString
 61 | 
 62 | 	updatedoutput.append(lupdateString[6:11])
 63 | 	updatedoutput.append("-")
 64 | 	updatedoutput.append(lupdateString[0:2])
 65 | 	updatedoutput.append("-")
 66 | 	updatedoutput.append(lupdateString[3:5])
 67 | 	updatedoutput.append(" 00:00:00")
 68 | 	
 69 | 	updatedFormattedString = ''.join(updatedoutput)
 70 | 	return updatedFormattedString
 71 | 
 72 | #checks on each type and adds corresponding code to the day array if true
 73 | def typesArray(meeting):
 74 | 	typesoutput = []
 75 | 
 76 | 	if(meeting["gsx$open"]["$t"]=="1"):
 77 | 		typesoutput.append("O")
 78 | 	else:
 79 | 		typesoutput.append("C")
 80 | 	if(meeting["gsx$mens"]["$t"]=="1"):
 81 | 		typesoutput.append("M")
 82 | 	typesArrayString = ''.join(typesoutput)
 83 | 	if(meeting["gsx$womens"]["$t"]=="1"):
 84 | 		typesoutput.append("W")
 85 | 	typesArrayString = ''.join(typesoutput)
 86 | 	if(meeting["gsx$handi"]["$t"]=="1"):
 87 | 		typesoutput.append("X")
 88 | 	typesArrayString = ''.join(typesoutput)
 89 | 	if(meeting["gsx$lgbtq"]["$t"]=="1"):
 90 | 		typesoutput.append("LGBTQ")
 91 | 	typesArrayString = ''.join(typesoutput)
 92 | 	if(meeting["gsx$spanish"]["$t"]=="1"):
 93 | 		typesoutput.append("S")
 94 | 	typesArrayString = ''.join(typesoutput)
 95 | 	if(meeting["gsx$kid"]["$t"]=="1"):
 96 | 		typesoutput.append("CF")
 97 | 	typesArrayString = ''.join(typesoutput)
 98 | 	if(meeting["gsx$si"]["$t"]=="1"):
 99 | 		typesoutput.append("ASL")
100 | 	typesArrayString = ''.join(typesoutput)
101 | 	if(meeting["gsx$alanon"]["$t"]=="1"):
102 | 		typesoutput.append("AL-AN")
103 | 	typesArrayString = ''.join(typesoutput)
104 | 	if(meeting["gsx$young"]["$t"]=="1"):
105 | 		typesoutput.append("Y")
106 | 	typesArrayString = ''.join(typesoutput)
107 | 	if(meeting["gsx$speaker"]["$t"]=="1"):
108 | 		typesoutput.append("SP")
109 | 
110 | 	return typesoutput
111 | 
112 | #properly formats the time into HH:MM from from stime_num integer
113 | def timeFormatted(meeting):
114 | 	timeoutput = []
115 | 
116 | 	if(int(meeting["gsx$time"]["$t"])<1000):
117 | 		timeoutput.append('0')
118 | 		timeoutput.append(meeting["gsx$time"]["$t"][:1])
119 | 	else:
120 | 		timeoutput.append(meeting["gsx$time"]["$t"][:2])
121 | 	timeoutput.append(':')
122 | 	timeoutput.append(meeting["gsx$time"]["$t"][-2:])
123 | 
124 | 	timeFormattedString = ''.join(timeoutput)
125 | 	return timeFormattedString
126 | 
127 | #checks on each day and adds corresponding integer to the day array if true
128 | def dayArray(meeting):
129 | 	dayoutput = []
130 | 
131 | 	if(meeting["gsx$sunday"]["$t"]=="1"):
132 | 		dayoutput.append(0)
133 | 	if(meeting["gsx$monday"]["$t"]=="1"):
134 | 		dayoutput.append(1)
135 | 	if(meeting["gsx$tuesday"]["$t"]=="1"):
136 | 		dayoutput.append(2)
137 | 	if(meeting["gsx$wednesday"]["$t"]=="1"):
138 | 		dayoutput.append(3)
139 | 	if(meeting["gsx$thursday"]["$t"]=="1"):
140 | 		dayoutput.append(4)
141 | 	if(meeting["gsx$friday"]["$t"]=="1"):
142 | 		dayoutput.append(5)
143 | 	if(meeting["gsx$saturday"]["$t"]=="1"):
144 | 		dayoutput.append(6)
145 | 
146 | 	return dayoutput
147 | 


--------------------------------------------------------------------------------
/import-scripts/san-antonio/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT
 25 | 		m.vid "slug",
 26 | 		(SELECT GROUP_CONCAT(t.name) FROM csosataxonomy_term_data t JOIN csosataxonomy_index i ON t.tid = i.tid WHERE t.vid = 3 AND i.nid = m.nid) day,
 27 | 		(SELECT GROUP_CONCAT(t.name) FROM csosataxonomy_term_data t JOIN csosataxonomy_index i ON t.tid = i.tid WHERE t.vid = 5 AND i.nid = m.nid) time,
 28 | 		m.title "name",
 29 | 		n.field_meeting_note_value "notes",
 30 | 		(SELECT GROUP_CONCAT(t.name) FROM csosataxonomy_term_data t JOIN csosataxonomy_index i ON t.tid = i.tid WHERE t.vid = 2 AND i.nid = m.nid) types,
 31 | 		m.changed "updated",
 32 | 		l.name "location",
 33 | 		l.street "address",
 34 | 		l.city "city",
 35 | 		l.province "state",
 36 | 		l.postal_code,
 37 | 		l.country,
 38 | 		l.additional "location_notes",
 39 | 		l.latitude,
 40 | 		l.longitude
 41 | 	FROM csosanode m
 42 | 	JOIN csosalocation_instance li ON m.vid = li.vid
 43 | 	JOIN csosalocation l on l.lid = li.lid
 44 | 	LEFT JOIN csosafield_data_field_meeting_note n ON n.revision_id = m.vid
 45 | 	WHERE m.type = "meeting"');
 46 | } catch (PDOException $e) {
 47 |     die('SQL query failed: ' . $e->getMessage());
 48 | }
 49 | 
 50 | function dd($obj) {
 51 | 	echo '
';
 52 | 	print_r($obj);
 53 | 	exit;
 54 | }
 55 | 
 56 | $type_lookup = array(
 57 | 	'Babysitting' => 'BA',
 58 | 	'Beginners' => 'BE',
 59 | 	'Big Book' => 'B',
 60 | 	//'Bilingual' => ''
 61 | 	//'Book Study' => '',
 62 | 	'Closed' => 'C',
 63 | 	'Discussion' => 'D',
 64 | 	'LGBT' => 'LGBTQ',
 65 | 	'Literature Study' => 'LIT',
 66 | 	'Men\'s' => 'M',
 67 | 	'No Smoking' => 'NS',
 68 | 	'Open' => 'O',
 69 | 	//'Podium' => ''
 70 | 	//'Senior'
 71 | 	'Smoking' => 'SM',
 72 | 	'Spanish' => 'S',
 73 | 	'Speaker\'s' => 'SP',
 74 | 	'Step Study' => 'ST',
 75 | 	//'Study-Three Legacies' => 
 76 | 	'Twelve & Twelve' => '12x12',
 77 | 	'Wheelchair Accessible' => 'X',
 78 | 	'Women' => 'W',
 79 | 	'Young People\'s' => 'YP',
 80 | );
 81 | 
 82 | $day_lookup = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
 83 | 
 84 | //fetch data
 85 | $return = array();
 86 | foreach ($result as $row) {
 87 | 
 88 | 	//turn comma-separated day into array of ints 0-6
 89 | 	$row['day'] = array_map(function($day) use ($day_lookup) {
 90 | 		return array_search($day, $day_lookup);
 91 | 	}, explode(',', $row['day']));
 92 | 
 93 | 	//turn comma-separated types into array of codes
 94 | 	$row['types'] = array_map(function($type) use ($type_lookup) {
 95 | 		return $type_lookup[$type];
 96 | 	}, array_filter(explode(',', $row['types']), function($key) use ($type_lookup) {
 97 | 		return array_key_exists($key, $type_lookup);
 98 | 	}));
 99 | 
100 | 	//format time
101 | 	$row['time'] = date('G:i', strtotime($row['time']));
102 | 
103 | 	//format updated
104 | 	$row['updated'] = date('c', $row['updated']);
105 | 
106 | 	//clean up numeric keys
107 | 	foreach ($row as $key => $value) {
108 | 	    if (is_int($key)) {
109 | 	        unset($row[$key]);
110 | 	    }
111 | 	}
112 | 
113 | 	//build array
114 | 	$return[] = $row;
115 | }
116 | 
117 | //encode JSON
118 | $return = json_encode($return);
119 | if (json_last_error()) {
120 | 	die('JSON error: ' . json_last_error_msg());
121 | }
122 | 
123 | //make sure headers haven't already been sent, will cause error
124 | if (headers_sent()) {
125 | 	die('Error: headers already sent!');
126 | }
127 | 
128 | //output
129 | header('Content-type: application/json; charset=utf-8');
130 | echo $return;
131 | 


--------------------------------------------------------------------------------
/import-scripts/san-francisco/san-francisco.cfm:
--------------------------------------------------------------------------------
 1 |  
 2 | 
 3 | 
 4 |  
 5 | 	select * from zlk_event_attributes;
 6 | 
 7 | 
 8 | 
 9 | 
10 | 	
11 | 		structInsert(aStruct,code,display_short);	
12 | 	
13 | 
14 |  
15 | 
16 | 
17 | 	select  
18 | 	coalesce(schedMeetingName,event_name) as name
19 | 	, meet_id as slug, 
20 | 	schedNote as notes, 
21 | 	convert(char(19),meeting_update,120) as updated, 
22 | 	'http://aasf.org/vm.cfm?s=' + cast(meet_id as char) as url,
23 | 	timesort as time, 
24 | 	day_id - 1 as day, 
25 | 	null as types, 
26 | 	m_bus_address1 as address, 
27 | 	m_bus_city as city, 
28 | 	m_bus_state as state, 
29 | 	m_bus_zip as postal_code,
30 | 	'US' as country, 
31 | 	latitude,
32 | 	longitude, 
33 | 	'American/Los Angeles' as timezone,
34 | 	bus_name as location,
35 | 	'http://aasf.org/viewsite.cfm?site_id=' + cast(bus_id as char) as location_url,
36 | 	bus_id as location_slug, 
37 | 	sitenote as location_notes,
38 | 	convert(char(19),
39 | 	bus_modified_date,120) as location_updated,
40 | 	discipline_areas,
41 | 	neighborhood as region
42 | 	from qry_meetings
43 | 	WHERE     (End_Date IS NULL) OR
44 |                       (CONVERT(char(8), End_Date, 112) >= CONVERT(char(8), GETDATE(), 112));
45 | 
46 |  
47 | 
48 | 
49 | 
50 | 
51 | [ 
52 | 
53 |  
54 | 	
55 | 	
56 | 	
57 | 		
58 | 		 
59 | 		
60 | 	
61 | 	
62 |  	
63 | 	, 
64 | 	{"name":"#name#","slug": "#slug#","notes":"#notes#","updated":"#updated#","url":"#trim(url)#","time":"#time#","day":"#day#","types":[#myD#],"address":"#address#","city":"#city#","state":"#state#","postal_code":"#postal_code#","country":"#country#","latitude":"#trim(latitude)#","longitude":"#trim(longitude)#","timezone":"#timezone#","location":"#location#","location_slug":"#location_slug#","location_notes":"#location_notes#","region":"#region#"} 
65 | 	 
66 | ]
67 | 
68 |  
69 | 
70 |   
71 |     
72 |  


--------------------------------------------------------------------------------
/import-scripts/santa-barbara/santa-barbara.php:
--------------------------------------------------------------------------------
  1 |  'C',
 43 | 	'SS' => 'ST',
 44 | 	'BB' => 'B',
 45 | 	'SPK' => 'SP',
 46 | 	'P' => 'D',
 47 | 	'H' => 'X',
 48 | 	'W' => 'W',
 49 | 	'M' => 'M',
 50 | 	'ME' => 'MED',
 51 | 	'GLBT' => 'LGBTQ',
 52 | 	'CC' => 'BA',
 53 | );
 54 | 
 55 | $decode_days = array(
 56 | 	'SUNDAY' => 0,
 57 | 	'MONDAY' => 1,
 58 | 	'TUESDAY' => 2,
 59 | 	'WEDNESDAY' => 3,
 60 | 	'THURSDAY' => 4,
 61 | 	'FRIDAY' => 5,
 62 | 	'SATURDAY' => 6,
 63 | );
 64 | 
 65 | //fetch data into array
 66 | $return = array();
 67 | while ($row = mysqli_fetch_assoc($result)) {
 68 | 
 69 | 	//format days
 70 | 	$days = explode(',', $row['day']);
 71 | 	$days = array_map('strtoupper', $days);
 72 | 	$days = array_map('trim', $days);
 73 | 	$row['day'] = array();
 74 | 	foreach ($days as $day) {
 75 | 		if (array_key_exists($day, $decode_days)) {
 76 | 			$row['day'][] = $decode_days[$day];
 77 | 		}
 78 | 	}
 79 | 	
 80 | 	//format time
 81 | 	$row['time'] = substr($row['time'], 0, 5);
 82 | 	
 83 | 	//format types
 84 | 	$types = explode(',', $row['types']);
 85 | 	$types = array_map('strtoupper', $types);
 86 | 	$types = array_map('trim', $types);
 87 | 	$row['types'] = array();
 88 | 	foreach ($types as $type) {
 89 | 		if (array_key_exists($type, $decode_types)) {
 90 | 			$row['types'][] = $decode_types[$type];
 91 | 		}
 92 | 	}
 93 | 	if ($row['meetings_is_spanish'] != '0') {
 94 | 		$row['types'][] = 'S';
 95 | 	}
 96 | 	$row['types'] = array_unique($row['types']);
 97 | 	unset($row['meetings_is_spanish']);
 98 | 	
 99 | 	$row['city'] = trim($row['city']);
100 | 	if (substr(strtoupper($row['city']), -4) == ', CA') {
101 | 		$row['city'] = substr($row['city'], 0, strlen($row['city']) - 4);
102 | 	}
103 | 	
104 | 	//additional
105 | 	$row['address'] = strip_tags($row['address']);
106 | 	$row['state'] = 'CA';
107 | 	$row['country'] = 'US';
108 | 	
109 | 	$return[] = $row;
110 | }
111 | 
112 | mysqli_free_result($result);
113 | mysqli_close($link);
114 | 
115 | //return JSON
116 | output($return);
117 | 
118 | //function to handle errors
119 | function error($string) {
120 | 	output(array(
121 | 		'error' => $string,
122 | 	));
123 | }
124 | 
125 | //function to output json
126 | function output($array) {
127 | 	$return = json_encode($array);
128 | 	if (json_last_error()) error(json_last_error_msg());
129 | 	die($return);
130 | }


--------------------------------------------------------------------------------
/import-scripts/southern-illinois/meetingguide.php:
--------------------------------------------------------------------------------
 1 |  ""');
 42 | 
 43 | //loop through
 44 | while ($meeting = mysql_fetch_array($meetings)) {
 45 | 
 46 | 	$meeting = array_map('trim', $meeting);
 47 | 
 48 | 	$slug			= $meeting['AutoNumber'];
 49 | 	$time			= $meeting['MeetingTime'];
 50 | 	$name			= $meeting['GroupName'];
 51 | 	$day			= $meeting['MeetingDayNum'] - 1;
 52 | 	$location		= $meeting['MeetingPlaceName'];
 53 | 	$notes			= $meeting['MeetingNotes'];
 54 | 	$address		= $meeting['MeetingAddress'];
 55 | 	$city = $region = $meeting['MeetingCity'];
 56 | 	$state			= empty($state) ? 'MO' : $meeting['MeetingState'];
 57 | 	$postal_code	= $meeting['MeetingZipCode'];
 58 | 	$country		= 'US';
 59 | 	
 60 | 	//some meetings are named "Meeting starts at 9:45am"
 61 | 	if (substr($name, 0, 18) == 'Meeting starts at ') {
 62 | 		$time = substr($name, 18);
 63 | 	}
 64 | 	
 65 | 	//fix for lois
 66 | 	if ($name == 'Nick of Time') $time = '12:15:00';
 67 | 
 68 | 	//remove neighborhood info from city name
 69 | 	if (substr($city, 0, 8) == 'St Louis') $city = 'St. Louis';
 70 | 
 71 | 	//types			
 72 | 	$types = array();
 73 | 	if ($meeting['MeetingBabySitting'] == 1) $types[] = 'BA'; //babysitting
 74 | 	if ($meeting['MeetingSmokingStatus'] == 2) $types[] = 'SM'; //smoking
 75 | 	if ($meeting['MeetingLanguage'] == 'SPANISH') $types[] = 'S';
 76 | 	if ($meeting['MeetingGenderID'] == 3) {
 77 | 		$types[] = 'M';
 78 | 	} elseif ($meeting['MeetingGenderID'] == 2) {
 79 | 		$types[] = 'W';
 80 | 	}
 81 | 	if ($meeting['MeetingStatus'] == 1) {
 82 | 		$types[] = 'O';
 83 | 	} elseif ($meeting['MeetingStatus'] == 2) {
 84 | 		$types[] = 'C';
 85 | 	}
 86 | 	if (($meeting['MeetingHandicapFacil'] == 1) || ($meeting['MeetingHandicapFacil'] == 2)) {
 87 | 		$types[] = 'X';
 88 | 	}
 89 | 	if ($meeting['NewComerMeeting'] == 'Y') $types[] = 'BE'; //beginner
 90 | 	
 91 | 	if (stristr($meeting['MeetingFormat'], 'step')) $types[] = 'ST';
 92 | 	if (stristr($meeting['MeetingFormat'], 'big book')) $types[] = 'BB';
 93 | 	if (stristr($meeting['MeetingFormat'], 'speaker')) $types[] = 'SP';
 94 | 	if (stristr($meeting['MeetingFormat'], 'tradition')) $types[] = 'TR';
 95 | 
 96 | 	switch($meeting['MeetingFormat']) {
 97 | 		case '12 X 12': 
 98 | 			$types[] = 'ST';
 99 | 			break;
100 | 		case '11th Step Med': 
101 | 			$types[] = 'MED';
102 | 			break;
103 | 		case 'AA / Alanon': 
104 | 			$types[] = 'AL-AN';
105 | 			break;
106 | 		case 'AA Literature Study': 
107 | 		case 'As Bill Sees It': 
108 | 		case 'Big Book/Living Sober': 
109 | 		case 'Came to Believe / Living Sober': 
110 | 		case 'Daily Reflections': 
111 | 		case 'Living Sober': 
112 | 			$types[] = 'LIT';
113 | 			break;
114 | 		case 'Birthday': 
115 | 			$types[] = 'H';
116 | 			break;
117 | 		case 'Candlelight': 
118 | 			$types[] = 'CAN';
119 | 			break;
120 | 		case 'Concepts/Step/Traditions': 
121 | 		case 'Grapevine': 
122 | 			$types[] = 'GR';
123 | 			break;
124 | 		case 'Topic': 
125 | 		case 'Topic/Discussion': 
126 | 		case 'Topic/Reading': 
127 | 		case 'Participation': 
128 | 		case 'Discussion': 
129 | 		case 'Duscussion': 
130 | 			$types[] = 'D';
131 | 			break;
132 | 		case 'Newcomer': 
133 | 			$types[] = 'BE';
134 | 			break;
135 | 		case 'Young People': 
136 | 			$types[] = 'Y';
137 | 			break;
138 | 	}
139 | 	
140 | 	$types = array_unique($types);
141 | 
142 | 	$return[] = compact('name', 'slug', 'day', 'time', 'location', 'address', 'city', 'state', 'region', 'postal_code', 'country', 'types');
143 | }
144 | 
145 | //output
146 | header('Content-type: application/json; charset=utf-8');
147 | echo json_encode($return);


--------------------------------------------------------------------------------
/import-scripts/suffolk-county/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT * FROM `2019_Suffolk_MG`');
 25 | } catch (PDOException $e) {
 26 |     die('SQL query failed: ' . $e->getMessage());
 27 | }
 28 | 
 29 | function dd($obj) {
 30 | 	echo '
';
 31 | 	print_r($obj);
 32 | 	exit;
 33 | }
 34 | 
 35 | function array_flatten($array, $return=array()) {
 36 | 	for ($x = 0; $x <= count($array); $x++) {
 37 | 		if (isset($array[$x])) {
 38 | 			if (is_array($array[$x])) {
 39 | 				$return = array_flatten($array[$x], $return);
 40 | 			} else {
 41 | 				$return[] = $array[$x];
 42 | 			}
 43 | 		}
 44 | 	}
 45 | 	return $return;
 46 | }
 47 | 
 48 | $type_lookup = array(
 49 | 	'A' => 'ASL', // ​American Sign Language
 50 | 	'ABSI' => 'ABSI', // As Bill Sees It
 51 | 	'ABSIT' => 'ABSI', // As Bill Sees It
 52 | 	'B' => 'BE', // Newcomer
 53 | 	'BB' => 'B', // Big Book
 54 | 	'BBOD' => array('B', 'O', 'D'), // Big Book, Open, Discussion
 55 | 	'BYOC' => 'C', // Bring Your Own Closed
 56 | 	'C' => 'C', // Closed
 57 | 	'CD' => array('C', 'D'), // Closed, Discussion
 58 | 	'DR' => 'DR', // Daily Reflections
 59 | 	'GV' => 'GR', // Grapevine
 60 | 	'LIT' => 'LIT', // Literature
 61 | 	'LS' => 'LS', // Living Sober
 62 | 	'M' => 'M', // Mens
 63 | 	'MC' => array('M', 'C'), // Mens, Closed
 64 | 	'MED' => 'MED', // Meditation
 65 | 	'MEDITATION' => 'MED', // Meditation
 66 | 	'O' => 'O', // Open
 67 | 	'OB' => array('O', 'BE'), // Open, Newcomer
 68 | 	'OBB' => array('O', 'B'), // Open, Big Book
 69 | 	'OD' => array('O', 'D'), // Open, Discussion
 70 | 	'ODB' => array('O', 'D', 'BE'), // Open, Discussion, Newcomer
 71 | 	'OS' => array('O', 'ST'), // Open, Step Meeting
 72 | 	//[24] => PROMISES = Promises
 73 | 	'S' => 'ST', // Step
 74 | 	'SP' => 'S', // Spanish
 75 | 	'T' => 'TR', // Tradition
 76 | 	'TOPIC' => 'D', // Topic
 77 | 	'W' => 'W', // Womens
 78 | 	'WC' => array('W', 'C'), // Womens, Closed
 79 | 	'WCD' => array('W', 'C', 'D'), // Womens, Closed, Discussion
 80 | 	'WS' => array('W', 'ST'), // Womens, Step Meeting
 81 | 	'YP' => 'YP', // Young People
 82 | );
 83 | 
 84 | $type_keys = array_keys($type_lookup);
 85 | 
 86 | $day_lookup = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 87 | 
 88 | $all_types = array();
 89 | 
 90 | //fetch data
 91 | $return = array();
 92 | foreach ($result as $row) {
 93 | 
 94 | 	//types
 95 | 	$row['new_type'] = str_replace(array(',', ';', ':'), ' ', strtoupper($row['new_type']));
 96 | 	$types = explode(' ', $row['new_type']);
 97 | 	//$all_types = array_merge($all_types, $types);
 98 | 	$types = array_filter($types, function($type) use ($type_keys) {
 99 | 		return in_array($type, $type_keys);
100 | 	});
101 | 	$types = array_map(function($type) use ($type_lookup) {
102 | 		return $type_lookup[$type];
103 | 	}, $types);
104 | 	$types = array_flatten($types);
105 | 
106 | 	//add C whenever meeting is not O
107 | 	//if (!in_array($types, 'O')) $types[] = 'C';
108 | 
109 | 	//build array
110 | 	$return[] = array(
111 | 		'slug' => $row['meeting_id'],
112 | 		'day' => array_search($row['new_day'], $day_lookup),
113 | 		'time' => date('H:i', strtotime($row['new_time'])),
114 | 		'name' => $row['group_name'],
115 | 		'types' => $types,
116 | 		'address' => $row['locationAddress'],
117 | 		'city' => $row['locationCity'],
118 | 		'state' => $row['locationState'],
119 | 		'postal_code' => $row['locationZip'],
120 | 		'country' => 'US',
121 | 		'notes' => $row['new_note'],
122 | 	);
123 | }
124 | 
125 | /*
126 | $all_types = array_unique($all_types);
127 | sort($all_types);
128 | dd($all_types);
129 | */
130 | 
131 | //encode JSON
132 | $return = json_encode($return);
133 | if (json_last_error()) {
134 | 	die('JSON error: ' . json_last_error_msg());
135 | }
136 | 
137 | //make sure headers haven't already been sent, will cause error
138 | if (headers_sent()) {
139 | 	die('Error: headers already sent!');
140 | }
141 | 
142 | //output
143 | header('Content-type: application/json; charset=utf-8');
144 | echo $return;
145 | 


--------------------------------------------------------------------------------
/import-scripts/tecmgc/tecmgc.php:
--------------------------------------------------------------------------------
  1 |  'B',
 23 | 		'CC' => 'C',
 24 | 		'D' => 'D',
 25 | 		'G' => 'G',
 26 | 		'H' => 'X',
 27 | 		'M' => 'M',
 28 | 		'N' => 'B',
 29 | 		'O' => 'O',
 30 | 		//PL—Pot Luck,
 31 | 		'S' => 'SP',
 32 | 		//SIS—Seniors in Sobriety,
 33 | 		'T' => 'ST',
 34 | 		'W' => 'W',
 35 | 		'Y' => 'Y',
 36 | 		'SP' => 'S',
 37 | 	);
 38 | 	
 39 | 	//fetch all the venues
 40 | 	$tribe_venues = get_posts(array(
 41 | 		'post_type' => 'tribe_venue',
 42 | 		'numberposts' => -1,
 43 | 	));
 44 | 	
 45 | 	//format the relevant venue information in a lookup array
 46 | 	foreach ($tribe_venues as $venue) {
 47 | 		$custom = get_post_meta($venue->ID);
 48 | 		$locations[$venue->ID] = array(
 49 | 			'location' => $venue->post_title,
 50 | 			'location_notes' => trim(strip_tags($venue->post_content)),
 51 | 			'address' => $custom['_VenueAddress'][0],
 52 | 			'city' => $custom['_VenueCity'][0],
 53 | 			'state' => $custom['_VenueState'][0],
 54 | 			'postal_code' => $custom['_VenueZip'][0],
 55 | 			'region' => $custom['_VenueCity'][0],
 56 | 		);
 57 | 	}
 58 | 	
 59 | 	//get the events for the next week (since they recur)
 60 | 	date_default_timezone_set(get_option('timezone_string'));
 61 | 	//dd($date_range);
 62 | 	
 63 | 	$tribe_events = tribe_get_events(array(
 64 | 		'post_type' => 'tribe_events',
 65 | 		'posts_per_page' => -1,
 66 | 		'start_date' => date('Y-m-d H:i:s', strtotime('+1 second')),
 67 | 		'end_date' => date('Y-m-d H:i:s', strtotime('+1 week')),
 68 | 	));
 69 | 	
 70 | 	//loop through and attach the correct info to each meeting listing
 71 | 	foreach ($tribe_events as $event) {
 72 | 	
 73 | 		//get metadata for event
 74 | 		$custom = get_post_meta($event->ID);
 75 | 	
 76 | 		//skip if no venue	
 77 | 		if (empty($custom['_EventVenueID'][0]) || !array_key_exists($custom['_EventVenueID'][0], $locations)) continue;
 78 | 	
 79 | 		//figure out the meeting types for this meeting
 80 | 		$meeting_types = array();
 81 | 		$type = tribe_get_custom_fields($event->ID);
 82 | 		if (!empty($type['Type'])) {
 83 | 			foreach ($types as $key => $value) {
 84 | 				if (strstr($type['Type'], $key)) {
 85 | 					$meeting_types[] = $value;
 86 | 				}
 87 | 			}
 88 | 		}
 89 | 
 90 | 		//skip empty locations
 91 | 		if (empty($locations[$custom['_EventVenueID'][0]]['city'])) continue;
 92 | 
 93 | 		//append meeting to the array
 94 | 		$meetings[] = array_merge(array(
 95 | 			'name' => $event->post_title,
 96 | 			'slug' => $event->post_parent ?: $event->ID,
 97 | 			'day' => date('w', strtotime($custom['_EventStartDate'][0])),
 98 | 			'time' => date('G:i', strtotime($custom['_EventStartDate'][0])),
 99 | 			'end_time' => date('G:i', strtotime($custom['_EventEndDate'][0])),
100 | 			'notes' => trim(strip_tags($event->post_content)),
101 | 			'url' => get_permalink($event->ID),
102 | 			'updated' => $event->post_modified_gmt,
103 | 			'types' => $meeting_types,
104 | 		), $locations[$custom['_EventVenueID'][0]]);
105 | 	}
106 | 	
107 | 	wp_send_json($meetings);
108 | }


--------------------------------------------------------------------------------
/import-scripts/tucson/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT
 25 | 			m.Meeting_ID `slug`,
 26 | 			(m.Day_ID - 1) `day`,
 27 | 			m.Time_24 `time`,
 28 | 			m.group_name2 `name`,
 29 | 			m.meeting_notes, 
 30 | 			m.location_notes,
 31 | 			m.Gender_ID,
 32 | 			i.interest,
 33 | 			m.format,
 34 | 			m.open_closed,
 35 | 			m.wc_access,
 36 | 			m.smoking,
 37 | 			l.location_name `location`,
 38 | 			l.address,
 39 | 			l.city,
 40 | 			l.zip `postal_code`,
 41 | 			l.area `region`,
 42 | 			l.map_notes
 43 | 		FROM meeting_schedule m
 44 | 		LEFT JOIN locations l ON m.Location_ID = l.Location_ID
 45 | 		LEFT JOIN interest i ON m.Interest_ID = i.Interest_ID');
 46 | } catch (PDOException $e) {
 47 |     die('SQL query failed: ' . $e->getMessage());
 48 | }
 49 | 
 50 | //fetch data
 51 | $return = array();
 52 | foreach ($result as $row) {
 53 | 	
 54 | 	//trim all values
 55 | 	$row = array_map('trim', $row);
 56 | 	
 57 | 	$types = array();
 58 | 	if ($row['Gender_ID'] == '1') $types[] = 'M';
 59 | 	if ($row['Gender_ID'] == '2') $types[] = 'W';
 60 | 	if ($row['interest'] == 'Spanish Speaking') $types[] = 'S';	
 61 | 	if ($row['interest'] == 'American Indian') $types[] = 'N';	
 62 | 	if ($row['interest'] == 'Young People') $types[] = 'Y';	
 63 | 	if ($row['interest'] == 'Gay') $types[] = 'G';
 64 | 	if ($row['interest'] == 'Lesbian') $types[] = 'L';
 65 | 	if ($row['interest'] == 'Gay/Lesbian') $types[] = 'LGBTQ';
 66 | 	if ($row['interest'] == 'Newcomer') $types[] = 'BE';
 67 | 	//if ($row['interest'] == 'Seniors 50-plus') $types[] = '';
 68 | 	if (stristr($row['format'], '11th Step')) $types[] = '11';
 69 | 	if (stristr($row['format'], 'BB')) $types[] = 'B';
 70 | 	if (stristr($row['format'], 'Big Book')) $types[] = 'B';
 71 | 	if (stristr($row['format'], '12 & 12')) $types[] = 'ST';
 72 | 	if (stristr($row['format'], 'Discussion')) $types[] = 'D';
 73 | 	if (stristr($row['format'], 'As Bill Sees It')) $types[] = 'ABSI';
 74 | 	if (stristr($row['format'], 'Newcomers')) $types[] = 'BE';
 75 | 	if (stristr($row['format'], 'Literature')) $types[] = 'LIT';
 76 | 	if (stristr($row['format'], 'Living Sober')) $types[] = 'LS';
 77 | 	if (stristr($row['format'], 'Meditation')) $types[] = 'MED';
 78 | 	if (stristr($row['format'], 'Speaker')) $types[] = 'SP';
 79 | 	if (stristr($row['format'], 'Step Study')) $types[] = 'ST';
 80 | 	if (stristr($row['format'], 'Traditions')) $types[] = 'T';
 81 | 	if ($row['wc_access'] == '(WH)') $types[] = 'X';	
 82 | 	if ($row['open_closed'] == '(O)') $types[] = 'O';	
 83 | 	if ($row['open_closed'] == '(C)') $types[] = 'C';	
 84 | 	if ($row['smoking'] == '(S)') $types[] = 'SM';	
 85 | 	if ($row['smoking'] == '(NS)') $types[] = 'NS';	
 86 | 	$types = array_unique($types);
 87 | 		
 88 | 	//notes
 89 | 	$notes = array();
 90 | 	if (!empty($row['meeting_notes'])) $notes[] = $row['meeting_notes'];
 91 | 	if (!empty($row['map_notes'])) $notes[] = $row['map_notes'];
 92 | 	if (!empty($row['location_notes'])) $notes[] = $row['location_notes'];
 93 | 	$notes = implode("\n", $notes);
 94 | 	
 95 | 	//build array
 96 | 	$return[] = array(
 97 | 		'slug' => $row['slug'],
 98 | 		'day' => intval($row['day']),
 99 | 		'name' => $row['name'],
100 | 		'time' => $row['time'],
101 | 		'types' => $types,
102 | 		'address' => $row['address'],
103 | 		'city' => $row['city'],
104 | 		'state' => 'AZ',
105 | 		'postal_code' => $row['postal_code'],
106 | 		'country' => 'US',
107 | 		'region' => $row['region'],
108 | 		'notes' => $notes,
109 | 	);
110 | }
111 | 
112 | 
113 | //encode JSON
114 | $return = json_encode($return);
115 | if (json_last_error()) {
116 | 	die('JSON error: ' . json_last_error_msg());
117 | }
118 | 
119 | //make sure headers haven't already been sent, will cause error
120 | if (headers_sent()) {
121 | 	die('Error: headers already sent!');
122 | }
123 | 
124 | //output
125 | header('Content-type: application/json; charset=utf-8');
126 | echo $return;
127 | 


--------------------------------------------------------------------------------
/import-scripts/tulsa/tulsa.php:
--------------------------------------------------------------------------------
 1 |  'ST', 'ABSI' => 'LIT', 'BBS' => 'B', 'Beg' => 'BE', 'CTB' => 'LIT', 'Cndl' => 'CAN', 'DR' => 'LIT',
13 | 	'Dis' => 'D', 'GV' => 'GR', 'LS' => 'LIT', 'Lit' => 'LIT', 'New' => 'B', 'Spk' => 'SP', 'St11' => 'ST', 'Step' => 'ST',
14 | 	'Top' => 'D', 'Trad' => 'TR',
15 | );
16 | 
17 | //connect to mysql
18 | $db = mysql_connect($server, $username, $password) or die('Unable to connect to MySQL!');
19 | mysql_select_db($database, $db) or die('Could not select database!');
20 | 	
21 | //select meetings
22 | $result = mysql_query('SELECT
23 | 		m.ID AS slug,
24 | 		m.day,
25 | 		m.time,
26 | 		m.isSmoking AS smoking,
27 | 		m.isMens AS men,
28 | 		m.isWomens AS women,
29 | 		m.isOpen AS open,
30 | 		m.Meeting_Comments AS notes,
31 | 		m.Group_ID AS location_slug,
32 | 		GREATEST(m.Meeting_Last_Update, l.Group_Last_Update) updated,
33 | 		l.Group_Name AS location_name,
34 | 		l.Group_Comments AS location_notes,
35 | 		l.Group_Address_1 AS address,
36 | 		l.Group_Address_2,
37 | 		l.Group_City AS city,
38 | 		l.Group_State AS state,
39 | 		l.Group_Zip AS postal_code,
40 | 		l.latitude,
41 | 		l.longitude,
42 | 		GROUP_CONCAT(m2t.MeetingType SEPARATOR ",") types
43 | 	FROM meetings m
44 | 	JOIN groups l ON m.Group_id = l.ID
45 | 	JOIN meetings_map_to_type m2t ON m.ID = m2t.MeetingID
46 | 	GROUP BY m.ID');
47 | 
48 | //loop through once and process each meeting
49 | while ($row = mysql_fetch_assoc($result)) {
50 | 	
51 | 	//append Group_Address_2 to location_notes if present
52 | 	if (!empty($row['Group_Address_2'])) {
53 | 		$row['location_notes'] .= PHP_EOL . $row['Group_Address_2'];
54 | 	}
55 | 	
56 | 	//handle types
57 | 	$row['types'] = explode(',', $row['types']);
58 | 	$types = array();
59 | 	foreach ($row['types'] as $type) {
60 | 		if (array_key_exists($type, $conversion)) {
61 | 			$types[] = $conversion[$type];
62 | 		}
63 | 	}
64 | 	if ($row['smoking']) $types[] = 'SM';
65 | 	if ($row['men']) $types[] = 'M';
66 | 	if ($row['women']) $types[] = 'W';
67 | 	if ($row['open']) $types[] = 'O';
68 | 	
69 | 	$meetings[] = array(
70 | 		'name' => $row['location_name'],
71 | 		'slug' => $row['slug'],
72 | 		'notes' => $row['notes'],
73 | 		'updated' => $row['updated'],
74 | 		'url' => null,
75 | 		'time' => $row['time'],
76 | 		'day' => --$row['day'],
77 | 		'types' => $types,
78 | 		'address' => $row['address'],
79 | 		'city' => $row['city'],
80 | 		'state' => $row['state'],
81 | 		'postal_code' => $row['postal_code'],
82 | 		'country' => 'US',
83 | 		'latitude' => $row['latitude'],
84 | 		'longitude' => $row['longitude'],
85 | 		'region' => $row['city'],
86 | 		'timezone' => 'America/Chicago',
87 | 		'location' => $row['location'],
88 | 		'location_slug' => $row['location_slug'],
89 | 		'location_notes' => trim($row['location_notes']),
90 | 	);
91 | }
92 | 
93 | header('Content-type: application/json; charset=utf-8');
94 | echo json_encode($meetings);


--------------------------------------------------------------------------------
/import-scripts/utah/meeting-guide.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 17 | }
 18 | 
 19 | //error handling
 20 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 21 | 
 22 | //select data
 23 | try {
 24 | 	$result = $pdo->query('SELECT * FROM list 
 25 | 		WHERE intergroup IS NULL OR intergroup NOT IN (
 26 | 			"Salt Lake Central Office", 
 27 | 			"Intergroup Services of Northern Utah",
 28 | 			"Northern Utah",
 29 | 			"Utah Valley Central Office"
 30 | 		)');
 31 | } catch (PDOException $e) {
 32 |     die('SQL query failed: ' . $e->getMessage());
 33 | }
 34 | 
 35 | function dd($obj) {
 36 | 	echo '
';
 37 | 	print_r($obj);
 38 | 	exit;
 39 | }
 40 | 
 41 | $day_lookup = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
 42 | 
 43 | //fetch data
 44 | $return = array();
 45 | 
 46 | foreach ($result as $row) {
 47 | 
 48 | 	$row = array_map('trim', $row);
 49 | 
 50 | 	$types = array();
 51 | 
 52 | 	//get types from accessible column
 53 | 	if (!empty($row['accessible']) && strtoupper($row['accessible']) !== 'N') {
 54 | 		$types[] = 'X'; //wheelchair access
 55 | 	}
 56 | 
 57 | 	//get types from sns column
 58 | 	if (!empty($row['sns']) && strtoupper($row['sns']) == 'S') {
 59 | 		$types[] = 'SM'; //smoking
 60 | 	}
 61 | 
 62 | 	//get types from type column
 63 | 	if (!empty($row['type'])) {
 64 | 		if (stristr($row['type'], 'book') || stristr($row['type'], 'bb')) $types[] = 'B'; //big book
 65 | 		if (stristr($row['type'], 'medi')) $types[] = 'MED'; //meditation
 66 | 		if (stristr($row['type'], 'new') || stristr($row['type'], 'begin')) $types[] = 'BE'; //meditation
 67 | 		if (stristr($row['type'], 'open')) {
 68 | 			$types[] = 'O'; //open
 69 | 		} elseif (stristr($row['type'], 'closed')) {
 70 | 			$types[] = 'C'; //women
 71 | 		}
 72 | 		if (stristr($row['type'], 'sign lang')) $types[] = 'ASL'; //sign language
 73 | 		if (stristr($row['type'], 'spanish')) $types[] = 'S'; //spanish
 74 | 		if (stristr($row['type'], 'speaker')) $types[] = 'SP'; //speaker
 75 | 		if (stristr($row['type'], 'step')) $types[] = 'ST'; //step meeting
 76 | 		if (stristr($row['type'], 'women')) {
 77 | 			$types[] = 'W'; //women
 78 | 		} elseif (stristr($row['type'], 'men')) {
 79 | 			$types[] = 'M'; //men
 80 | 		}
 81 | 		if (stristr($row['type'], 'young')) $types[] = 'YP'; //step meeting
 82 | 	}
 83 | 
 84 | 	//split location notes from location
 85 | 	$notes = array();
 86 | 
 87 | 	if ($pos = strpos($row['address2'], '-')) {
 88 | 		$notes[] = trim(substr($row['address2'], $pos + 1));
 89 | 		$row['address2'] = trim(substr($row['address2'], 0, $pos));
 90 | 	}
 91 | 
 92 | 	if ($pos = strpos($row['address2'], ',')) {
 93 | 		$notes[] = trim(substr($row['address2'], $pos + 1));
 94 | 		$row['address2'] = trim(substr($row['address2'], 0, $pos));
 95 | 	}
 96 | 
 97 | 	//build array
 98 | 	$return[] = array(
 99 | 		'slug' => $row['ID'],
100 | 		'day' => array_search($row['day'], $day_lookup),
101 | 		'time' => substr($row['timesort'], 0, 5),
102 | 		'name' => $row['name'],
103 | 		'types' => $types,
104 | 		'address' => $row['address'],
105 | 		'location' => $row['address2'],
106 | 		'city' => $row['city'],
107 | 		'state' => 'UT',
108 | 		'country' => 'US',
109 | 		'notes' => implode("\n", $notes),
110 | 	);
111 | }
112 | 
113 | 
114 | //encode JSON
115 | $return = json_encode($return);
116 | if (json_last_error()) {
117 | 	die('JSON error: ' . json_last_error_msg());
118 | }
119 | 
120 | //make sure headers haven't already been sent, will cause error
121 | if (headers_sent()) {
122 | 	die('Error: headers already sent!');
123 | }
124 | 
125 | //output
126 | header('Content-type: application/json; charset=utf-8');
127 | echo $return;
128 | 


--------------------------------------------------------------------------------
/import-scripts/winston-salem/winston-salem.php:
--------------------------------------------------------------------------------
  1 | getMessage());
 38 | }
 39 | 
 40 | //error handling
 41 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 42 | 
 43 | //select data
 44 | try {
 45 | 	$result = $pdo->query($sql);
 46 | } catch (PDOException $e) {
 47 |     die('SQL query failed: ' . $e->getMessage());
 48 | }
 49 | 
 50 | //type definitions
 51 | $decode_days = array(
 52 | 	'Sunday' => 0,
 53 | 	'Monday' => 1,
 54 | 	'Tuesday' => 2,
 55 | 	'Wednesday' => 3,
 56 | 	'Thursday' => 4,
 57 | 	'Friday' => 5,
 58 | 	'Saturday' => 6,
 59 | );
 60 | 
 61 | $decode_types = array(
 62 | 	'Beginners' => 'BE',
 63 | 	'Child friendly; well-behaved children are welcome. No nursery provided.' => 'CF',
 64 | 	'Discussion' => 'D',
 65 | 	'Literature' => 'LIT',
 66 | 	'Speaker' => 'SP',
 67 | );
 68 | 
 69 | //fetch data
 70 | $return = array();
 71 | foreach ($result as $row) {
 72 | 	
 73 | 	//trim all values
 74 | 	$row = array_map('trim', $row);
 75 | 	
 76 | 	//make sure day is valid
 77 | 	if (!array_key_exists($row['day'], $decode_days)) continue;
 78 | 	
 79 | 	//set types
 80 | 	$types = array();
 81 | 	if (array_key_exists($row['type'], $decode_types)) $types[] = $decode_types[$row['type']];
 82 | 	if ($row['open_closed'] == 'Open') $types[] = 'O';
 83 | 	if ($row['open_closed'] == 'Closed') $types[] = 'C';
 84 | 	if (!empty($row['spanish'])) $types[] = 'S';
 85 | 	if (!empty($row['haccess'])) $types[] = 'X';
 86 | 	if (stristr($row['affiltn'], 'women')) $types[] = 'W';
 87 | 	
 88 | 	//notes
 89 | 	if (!empty($row['affiltn'])) {
 90 | 		if (!empty($row['notes'])) $row['notes'] .= '
'; 91 | $row['notes'] .= $row['affiltn']; 92 | } 93 | 94 | //build array 95 | $return[] = array( 96 | 'slug' => $row['id'], 97 | 'day' => $decode_days[$row['day']], 98 | 'name' => $row['name'], 99 | 'location' => $row['location'], 100 | 'group' => $row['group'], 101 | 'notes' => $row['notes'], 102 | 'time' => date('H:i', strtotime($row['time'])), 103 | 'types' => $types, 104 | 'address' => $row['address'], 105 | 'city' => $row['city'], 106 | 'state' => $row['state'], 107 | 'postal_code' => $row['zipcode'], 108 | 'region' => $row['city'], 109 | ); 110 | } 111 | 112 | 113 | //encode JSON 114 | $return = json_encode($return); 115 | if (json_last_error()) { 116 | die('JSON error: ' . json_last_error_msg()); 117 | } 118 | 119 | //make sure headers haven't already been sent, will cause error 120 | if (headers_sent()) { 121 | die('Error: headers already sent!'); 122 | } 123 | 124 | //output 125 | header('Content-type: application/json; charset=utf-8'); 126 | echo $return; 127 | -------------------------------------------------------------------------------- /jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code4recovery/spec", 3 | "version": "1.1.6", 4 | "description": "The goal of the Meeting Guide API is help sync information about AA meetings. It was developed for the Meeting Guide app, but it is non-proprietary and other systems are encouraged to make use of it.", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "files": [ 8 | "lib/**/*" 9 | ], 10 | "scripts": { 11 | "test": "jest --config jestconfig.json", 12 | "test-coverage": "jest --config jestconfig.json --coverage", 13 | "build": "tsc", 14 | "format": "prettier --write \"src/**/*.ts\"", 15 | "lint": "tslint -p tsconfig.json", 16 | "prepare": "npm run build", 17 | "prepublishOnly": "npm test && npm run lint", 18 | "preversion": "npm run lint", 19 | "version": "npm run format && git add -A src", 20 | "postversion": "git push && git push --tags" 21 | }, 22 | "keywords": [ 23 | "AA", 24 | "meetings", 25 | "JSON" 26 | ], 27 | "author": "Code for Recovery", 28 | "license": "MIT", 29 | "devDependencies": { 30 | "@types/jest": "^29.5.2", 31 | "jest": "^29.5.0", 32 | "prettier": "^2.8.8", 33 | "ts-jest": "^29.1.0", 34 | "tslint": "^6.1.3", 35 | "tslint-config-prettier": "^1.18.0", 36 | "typescript": "^5.1.3" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Spec.php: -------------------------------------------------------------------------------- 1 | 'English', 9 | 'es' => 'Español', 10 | 'fr' => 'Français', 11 | 'ja' => '日本語', 12 | 'nl' => 'Nederlands', 13 | 'pt' => 'Português', 14 | 'sk' => 'Slovenčina', 15 | 'sv' => 'Svenska', 16 | ]; 17 | 18 | /** 19 | * Get all languages. 20 | * 21 | * Retrieves and returns all languages with language code and expanded language translation that is stored 22 | * in the type repository. 23 | * 24 | * @return string[] 25 | */ 26 | public static function getLanguages(): array 27 | { 28 | return self::$languages; 29 | } 30 | 31 | /** 32 | * Get all types. 33 | * 34 | * Retrieves and returns all types stored in the type repository. 35 | * 36 | * @return object The array of all types. 37 | */ 38 | public static function getAllTypes(): object 39 | { 40 | $types = include 'types.php'; 41 | return $types; 42 | } 43 | 44 | /** 45 | * Returns an array of types translated into the specified language. 46 | * 47 | * @param string $language The language code to retrieve the translations 48 | * for. 49 | * 50 | * @return array An array of type translations in the specified language. 51 | */ 52 | public static function getTypesByLanguage(string $language): array 53 | { 54 | $typesByLanguage = []; 55 | $types = self::getAllTypes(); 56 | foreach ($types as $typeKey => $typeTranslations) { 57 | if (isset($typeTranslations->$language)) { 58 | $typesByLanguage[$typeKey] = $typeTranslations->$language; 59 | } 60 | } 61 | return $typesByLanguage; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | isMeetingType, 3 | isSupportedLanguage, 4 | getTypesForLanguage, 5 | } from "../index"; 6 | 7 | describe("isMeetingType", () => { 8 | it("should return true for supported meeting types", () => { 9 | expect(isMeetingType("T")).toBe(true); 10 | }); 11 | 12 | it("should return false for unsupported meeting types", () => { 13 | expect(isMeetingType("FOO")).toBe(false); 14 | }); 15 | 16 | it("should return true for supported language", () => { 17 | expect(isSupportedLanguage("en")).toBe(true); 18 | }); 19 | 20 | it("should return false for unsupported language", () => { 21 | expect(isSupportedLanguage("FOO")).toBe(false); 22 | }); 23 | 24 | it("should return supported languages", () => { 25 | const enTypes = getTypesForLanguage("en"); 26 | expect(Object.keys(enTypes)).toHaveLength(87); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { languages } from "./languages"; 2 | import { types } from "./types"; 3 | 4 | export type Language = (typeof languages)[number]; 5 | export type MeetingType = keyof typeof types; 6 | 7 | export function isMeetingType(type: string): type is MeetingType { 8 | return type in types; 9 | } 10 | 11 | export function isSupportedLanguage(language: string): language is Language { 12 | return languages.includes(language as Language); 13 | } 14 | 15 | export function getTypesForLanguage(language: string) { 16 | const typesForLanguage: Record = {} as any; 17 | for (const type in types) { 18 | if (isMeetingType(type) && isSupportedLanguage(language)) { 19 | typesForLanguage[type] = types[type][language]; 20 | } 21 | } 22 | return typesForLanguage; 23 | } 24 | -------------------------------------------------------------------------------- /src/languages.ts: -------------------------------------------------------------------------------- 1 | export const languages = [ 2 | "en", 3 | "es", 4 | "fr", 5 | "ja", 6 | "nl", 7 | "pt", 8 | "sk", 9 | "sv", 10 | ] as const; 11 | -------------------------------------------------------------------------------- /src/types.php: -------------------------------------------------------------------------------- 1 | 5 | (object) array( 6 | 'en' => '11th Step Meditation', 7 | 'es' => 'Meditación del Paso 11', 8 | 'fr' => 'Méditation sur la 11e Étape', 9 | 'ja' => 'ステップ11 黙想', 10 | 'nl' => 'Stap 11 meditatie', 11 | 'pt' => 'Meditação do 11º Passo', 12 | 'sk' => 'Meditácia 11. kroku', 13 | 'sv' => '11th Stegs Meditation', 14 | ), 15 | '12x12' => 16 | (object) array( 17 | 'en' => '12 Steps & 12 Traditions', 18 | 'es' => '12 Pasos y 12 Tradiciones', 19 | 'fr' => '12 Étapes et 12 Traditions', 20 | 'ja' => '12のステップと12の伝統', 21 | 'nl' => '12 Stappen en 12 Tradities', 22 | 'pt' => '12 Passos e 12 Tradições', 23 | 'sk' => '12 Krokov & 12 Tradícií', 24 | 'sv' => '12 Steg & 12 Traditioner', 25 | ), 26 | 'A' => 27 | (object) array( 28 | 'en' => 'Secular', 29 | 'es' => 'Secular', 30 | 'fr' => 'Séculier', 31 | 'ja' => '無宗教', 32 | 'nl' => 'Seculier', 33 | 'pt' => 'Secular', 34 | 'sk' => 'Svetské', 35 | 'sv' => 'Sekulärt', 36 | ), 37 | 'ABSI' => 38 | (object) array( 39 | 'en' => 'As Bill Sees It', 40 | 'es' => 'Como lo ve Bill', 41 | 'fr' => 'Réflexions de Bill', 42 | 'ja' => 'ビルはこう思う', 43 | 'nl' => 'Zoals Bill het ziet', 44 | 'pt' => 'Na opinião de Bill', 45 | 'sk' => 'Ako to vidí Bill', 46 | 'sv' => 'Som Bill Ser Det', 47 | ), 48 | 'AF' => 49 | (object) array( 50 | 'en' => 'Afrikaans', 51 | 'es' => 'Afrikáans', 52 | 'fr' => 'Afrikaans', 53 | 'ja' => 'アフリカーンス語', 54 | 'nl' => 'Afrikaans', 55 | 'pt' => 'Afrikaans', 56 | 'sk' => 'Afrikánčina', 57 | 'sv' => 'Afrikaans', 58 | ), 59 | 'AL' => 60 | (object) array( 61 | 'en' => 'Concurrent with Alateen', 62 | 'es' => 'Concurrente con Alateen', 63 | 'fr' => 'En même temps qu’Alateen', 64 | 'ja' => 'アラティーンと同時進行', 65 | 'nl' => 'Gelijktijdig met Alateen', 66 | 'pt' => 'Em simultâneo com Alateen', 67 | 'sk' => 'Súbežne s Alateen', 68 | 'sv' => 'Tillsammans med Alateen', 69 | ), 70 | 'AL-AN' => 71 | (object) array( 72 | 'en' => 'Concurrent with Al-Anon', 73 | 'es' => 'Concurrente con Al-Anon', 74 | 'fr' => 'En même temps qu’Al-Anon', 75 | 'ja' => 'アラノンと同時進行', 76 | 'nl' => 'Gelijktijdig met Al-Anon', 77 | 'pt' => 'Em simultâneo com Al-Anon', 78 | 'sk' => 'Súbežne s Al-Anon', 79 | 'sv' => 'Tillsammans med Al-Anon', 80 | ), 81 | 'AM' => 82 | (object) array( 83 | 'en' => 'Amharic', 84 | 'es' => 'Amárico', 85 | 'fr' => 'Amharique', 86 | 'ja' => 'アムハラ語', 87 | 'nl' => 'Amhaars', 88 | 'pt' => 'Amárico', 89 | 'sk' => 'Amharčina', 90 | 'sv' => 'Amhariska', 91 | ), 92 | 'AR' => 93 | (object) array( 94 | 'en' => 'Arabic', 95 | 'es' => 'Árabe', 96 | 'fr' => 'Arabe', 97 | 'ja' => 'アラビア語', 98 | 'nl' => 'Arabisch', 99 | 'pt' => 'Árabe', 100 | 'sk' => 'Arabské', 101 | 'sv' => 'Arabiska', 102 | ), 103 | 'ASL' => 104 | (object) array( 105 | 'en' => 'American Sign Language', 106 | 'es' => 'Lenguaje por señas', 107 | 'fr' => 'Langage des Signes', 108 | 'ja' => 'アメリカ手話', 109 | 'nl' => 'Amerikaanse gebaren taal', 110 | 'pt' => 'Língua Gestual Americana', 111 | 'sk' => 'Americký posunkový jazyk', 112 | 'sv' => 'Amerikanskt teckenspråk', 113 | ), 114 | 'B' => 115 | (object) array( 116 | 'en' => 'Big Book', 117 | 'es' => 'Libro Grande', 118 | 'fr' => 'Gros Livre', 119 | 'ja' => 'ビッグブック', 120 | 'nl' => 'Big Book', 121 | 'pt' => 'Livro Azul', 122 | 'sk' => 'Veľká Kniha', 123 | 'sv' => 'Stora Boken', 124 | ), 125 | 'BA' => 126 | (object) array( 127 | 'en' => 'Babysitting Available', 128 | 'es' => 'Guardería disponible', 129 | 'fr' => 'Garderie d’enfants disponible', 130 | 'ja' => 'ベビーシッターあり', 131 | 'nl' => 'Kinderopvang aanwezig', 132 | 'pt' => 'Babysitting disponível', 133 | 'sk' => 'Dostupné opatrovanie detí', 134 | 'sv' => 'Barnvakt Finns', 135 | ), 136 | 'BE' => 137 | (object) array( 138 | 'en' => 'Newcomer', 139 | 'es' => 'Principiantes', 140 | 'fr' => 'Nouveau/nouvelle', 141 | 'ja' => 'ビギナーズ', 142 | 'nl' => 'Nieuwkomer', 143 | 'pt' => 'Recém-chegados', 144 | 'sk' => 'Nováčikovia', 145 | 'sv' => 'Nykomling', 146 | ), 147 | 'BG' => 148 | (object) array( 149 | 'en' => 'Bulgarian', 150 | 'es' => 'Búlgaro', 151 | 'fr' => 'Bulgare', 152 | 'ja' => 'ブルガリア語', 153 | 'nl' => 'Bulgaars', 154 | 'pt' => 'Búlgaro', 155 | 'sk' => 'Bulharské', 156 | 'sv' => 'Bulgariska', 157 | ), 158 | 'BI' => 159 | (object) array( 160 | 'en' => 'Bisexual', 161 | 'es' => 'Bisexual', 162 | 'fr' => 'Bisexuel', 163 | 'ja' => 'バイセクシャル', 164 | 'nl' => 'Biseksueel', 165 | 'pt' => 'Bisexual', 166 | 'sk' => 'Bisexuálne', 167 | 'sv' => 'Bisexuellt', 168 | ), 169 | 'BRK' => 170 | (object) array( 171 | 'en' => 'Breakfast', 172 | 'es' => 'Desayuno', 173 | 'fr' => 'Petit déjeuner', 174 | 'ja' => '朝食', 175 | 'nl' => 'Ontbijt', 176 | 'pt' => 'Pequeno-Almoço', 177 | 'sk' => 'Raňajky', 178 | 'sv' => 'Frukost', 179 | ), 180 | 'C' => 181 | (object) array( 182 | 'en' => 'Closed', 183 | 'es' => 'Cerrada', 184 | 'fr' => 'Fermé', 185 | 'ja' => 'クローズド', 186 | 'nl' => 'Gesloten', 187 | 'pt' => 'Fechada', 188 | 'sk' => 'Uzatvorené', 189 | 'sv' => 'Slutet', 190 | ), 191 | 'CAN' => 192 | (object) array( 193 | 'en' => 'Candlelight', 194 | 'es' => 'Luz de una vela', 195 | 'fr' => 'À la chandelle', 196 | 'ja' => 'キャンドル', 197 | 'nl' => 'Candlelight', 198 | 'pt' => 'Luz de Velas', 199 | 'sk' => 'Sviečky', 200 | 'sv' => 'Tända Ljus', 201 | ), 202 | 'CF' => 203 | (object) array( 204 | 'en' => 'Child-Friendly', 205 | 'es' => 'Niño amigable', 206 | 'fr' => 'Enfants acceptés', 207 | 'ja' => 'お子さま歓迎', 208 | 'nl' => 'Kindvriendelijk', 209 | 'pt' => 'Amigável para Crianças', 210 | 'sk' => 'Priateľský k deťom', 211 | 'sv' => 'Barnvänligt', 212 | ), 213 | 'D' => 214 | (object) array( 215 | 'en' => 'Discussion', 216 | 'es' => 'Discusión', 217 | 'fr' => 'Discussion', 218 | 'ja' => 'ディスカッション', 219 | 'nl' => 'Discussie', 220 | 'pt' => 'Discussão', 221 | 'sk' => 'Diskusia', 222 | 'sv' => 'Diskussion', 223 | ), 224 | 'DA' => 225 | (object) array( 226 | 'en' => 'Danish', 227 | 'es' => 'Danés', 228 | 'fr' => 'Danois', 229 | 'ja' => 'デンマーク語', 230 | 'nl' => 'Deens', 231 | 'pt' => 'Dinamarquês', 232 | 'sk' => 'Dánsky', 233 | 'sv' => 'Danska', 234 | ), 235 | 'DB' => 236 | (object) array( 237 | 'en' => 'Digital Basket', 238 | 'es' => 'Canasta digital', 239 | 'fr' => 'Panier numérique', 240 | 'ja' => '電子献金', 241 | 'nl' => 'Digitale mand', 242 | 'pt' => 'Cesto Digital', 243 | 'sk' => 'Digitálny košík', 244 | 'sv' => 'Digital Korg', 245 | ), 246 | 'DD' => 247 | (object) array( 248 | 'en' => 'Dual Diagnosis', 249 | 'es' => 'Diagnóstico dual', 250 | 'fr' => 'Double diagnostic', 251 | 'ja' => '重複診断', 252 | 'nl' => 'Dubbele diagnose', 253 | 'pt' => 'Duplo Diagnóstico', 254 | 'sk' => 'Duálna diagnóza', 255 | 'sv' => 'Dubbel Diagnos', 256 | ), 257 | 'DE' => 258 | (object) array( 259 | 'en' => 'German', 260 | 'es' => 'Alemán', 261 | 'fr' => 'Allemand', 262 | 'ja' => 'ドイツ語', 263 | 'nl' => 'Duits', 264 | 'pt' => 'Alemão', 265 | 'sk' => 'Nemecké', 266 | 'sv' => 'Tyska', 267 | ), 268 | 'DR' => 269 | (object) array( 270 | 'en' => 'Daily Reflections', 271 | 'es' => 'Reflexiones Diarias', 272 | 'fr' => 'Réflexions quotidiennes', 273 | 'ja' => '今日を新たに', 274 | 'nl' => 'Dagelijkse weerspiegelingen', 275 | 'pt' => 'Reflexões Diárias', 276 | 'sv' => 'Dagliga Reflektioner', 277 | 'sk' => 'Denné úvahy', 278 | ), 279 | 'EL' => 280 | (object) array( 281 | 'en' => 'Greek', 282 | 'es' => 'Griego', 283 | 'fr' => 'Grec', 284 | 'ja' => 'ギリシャ語', 285 | 'nl' => 'Grieks', 286 | 'pt' => 'Grego', 287 | 'sk' => 'Grécke', 288 | 'sv' => 'Grekiska', 289 | ), 290 | 'EN' => 291 | (object) array( 292 | 'en' => 'English', 293 | 'es' => 'Inglés', 294 | 'fr' => 'Anglais', 295 | 'ja' => '英語', 296 | 'nl' => 'Engels', 297 | 'pt' => 'Inglês', 298 | 'sk' => 'Anglické', 299 | 'sv' => 'Engelska', 300 | ), 301 | 'FA' => 302 | (object) array( 303 | 'en' => 'Persian', 304 | 'es' => 'Persa', 305 | 'fr' => 'Persan', 306 | 'ja' => 'ペルシア語', 307 | 'nl' => 'Perzisch', 308 | 'pt' => 'Persa', 309 | 'sk' => 'Perzské', 310 | 'sv' => 'Persiska', 311 | ), 312 | 'FI' => 313 | (object) array( 314 | 'en' => 'Finnish', 315 | 'es' => 'Finlandés', 316 | 'fr' => 'Finlandais', 317 | 'ja' => 'フィンランド語', 318 | 'nl' => 'Fins', 319 | 'pt' => 'Finlandês', 320 | 'sk' => 'Fínčina', 321 | 'sv' => 'Finska', 322 | ), 323 | 'FF' => 324 | (object) array( 325 | 'en' => 'Fragrance Free', 326 | 'es' => 'Sin fragancia', 327 | 'fr' => 'Sans parfum', 328 | 'ja' => '香水なし', 329 | 'nl' => 'Geen parfum', 330 | 'pt' => 'Sem Perfumes', 331 | 'sk' => 'Bez vône', 332 | 'sv' => 'Parfym Fritt', 333 | ), 334 | 'FR' => 335 | (object) array( 336 | 'en' => 'French', 337 | 'es' => 'Francés', 338 | 'fr' => 'Français', 339 | 'ja' => 'フランス語', 340 | 'nl' => 'Frans', 341 | 'pt' => 'Francês', 342 | 'sk' => 'Francúzsky', 343 | 'sv' => 'Franska', 344 | ), 345 | 'G' => 346 | (object) array( 347 | 'en' => 'Gay', 348 | 'es' => 'Gay', 349 | 'fr' => 'Gai', 350 | 'ja' => 'ゲイ', 351 | 'nl' => 'Homo', 352 | 'pt' => 'Gay', 353 | 'sk' => 'Gay', 354 | 'sv' => 'Gay', 355 | ), 356 | 'GR' => 357 | (object) array( 358 | 'en' => 'Grapevine', 359 | 'es' => 'La Viña', 360 | 'fr' => 'Grapevine', 361 | 'ja' => 'グレープバイン', 362 | 'nl' => 'Wijnstok', 363 | 'pt' => 'Grapevine', 364 | 'sk' => 'Grapevine', 365 | 'sv' => 'Grapevine', 366 | ), 367 | 'H' => 368 | (object) array( 369 | 'en' => 'Birthday', 370 | 'es' => 'Cumpleaños', 371 | 'fr' => 'Anniversaire', 372 | 'ja' => 'バースデー', 373 | 'nl' => 'Verjaardag', 374 | 'pt' => 'Aniversário', 375 | 'sk' => 'Narodeniny', 376 | 'sv' => 'Födelsedag', 377 | ), 378 | 'HE' => 379 | (object) array( 380 | 'en' => 'Hebrew', 381 | 'es' => 'Hebreo', 382 | 'fr' => 'Hébreu', 383 | 'ja' => 'ヘブライ語', 384 | 'nl' => 'Hebreeuws', 385 | 'pt' => 'Hebreu', 386 | 'sk' => 'Hebrejské', 387 | 'sv' => 'Hebreiska', 388 | ), 389 | 'HI' => 390 | (object) array( 391 | 'en' => 'Hindi', 392 | 'es' => 'Hindi', 393 | 'fr' => 'Hindi', 394 | 'ja' => 'ヒンディー語', 395 | 'nl' => 'Hindi', 396 | 'pt' => 'Hindi', 397 | 'sk' => 'Hindi', 398 | 'sv' => 'Hindi', 399 | ), 400 | 'HR' => 401 | (object) array( 402 | 'en' => 'Croatian', 403 | 'es' => 'Croata', 404 | 'fr' => 'Croate', 405 | 'ja' => 'クロアチア語', 406 | 'nl' => 'Kroatisch', 407 | 'pt' => 'Croata', 408 | 'sk' => 'Chorvátsky', 409 | 'sv' => 'Kroatiska', 410 | ), 411 | 'HU' => 412 | (object) array( 413 | 'en' => 'Hungarian', 414 | 'es' => 'Húngaro', 415 | 'fr' => 'Hongrois', 416 | 'ja' => 'ハンガリー語', 417 | 'nl' => 'Hongaars', 418 | 'pt' => 'Hungaro', 419 | 'sk' => 'Maďarské', 420 | 'sv' => 'Ungerska', 421 | ), 422 | 'IS' => 423 | (object) array( 424 | 'en' => 'Icelandic', 425 | 'es' => 'Islandés', 426 | 'fr' => 'Islandais', 427 | 'ja' => 'アイスランド語', 428 | 'nl' => 'IJslands', 429 | 'pt' => 'Islandês', 430 | 'sk' => 'Islanské', 431 | 'sv' => 'Isländska', 432 | ), 433 | 'ITA' => 434 | (object) array( 435 | 'en' => 'Italian', 436 | 'es' => 'Italiano', 437 | 'fr' => 'Italien', 438 | 'ja' => 'イタリア語', 439 | 'nl' => 'Italiaans', 440 | 'pt' => 'Italiano', 441 | 'sk' => 'Taliansky', 442 | 'sv' => 'Italienska', 443 | ), 444 | 'JA' => 445 | (object) array( 446 | 'en' => 'Japanese', 447 | 'es' => 'Japonés', 448 | 'fr' => 'Japonais', 449 | 'ja' => '日本語', 450 | 'nl' => 'Japans', 451 | 'pt' => 'Japonês', 452 | 'sk' => 'Japonské', 453 | 'sv' => 'Japanska', 454 | ), 455 | 'KA' => 456 | (object) array( 457 | 'en' => 'Georgian', 458 | 'es' => 'Georgiano', 459 | 'fr' => 'Géorgien', 460 | 'ja' => 'ジョージア語', 461 | 'nl' => 'Georgisch', 462 | 'pt' => 'Georgiano', 463 | 'sk' => 'Gruzínske', 464 | 'sv' => 'Georgiska', 465 | ), 466 | 'KOR' => 467 | (object) array( 468 | 'en' => 'Korean', 469 | 'es' => 'Coreano', 470 | 'fr' => 'Coréen', 471 | 'ja' => '韓国語', 472 | 'nl' => 'Koreaans', 473 | 'pt' => 'Coreano', 474 | 'sk' => 'Kórejske', 475 | 'sv' => 'Koreanska', 476 | ), 477 | 'L' => 478 | (object) array( 479 | 'en' => 'Lesbian', 480 | 'es' => 'Lesbiana', 481 | 'fr' => 'Lesbienne', 482 | 'ja' => 'レズビアン', 483 | 'nl' => 'Lesbisch', 484 | 'pt' => 'Lésbica', 485 | 'sk' => 'Lesbické', 486 | 'sv' => 'Lesbiskt', 487 | ), 488 | 'LGBTQ' => 489 | (object) array( 490 | 'en' => 'LGBTQ', 491 | 'es' => 'LGBTQ', 492 | 'fr' => 'LGBTQ', 493 | 'ja' => 'LGBTQ', 494 | 'nl' => 'LGBTQ', 495 | 'pt' => 'LGBTQ', 496 | 'sk' => 'LGBTQ', 497 | 'sv' => 'HBTQ', 498 | ), 499 | 'LIT' => 500 | (object) array( 501 | 'en' => 'Literature', 502 | 'es' => 'Literatura', 503 | 'fr' => 'Publications', 504 | 'ja' => '書籍', 505 | 'nl' => 'Literatuur', 506 | 'pt' => 'Literatura', 507 | 'sk' => 'Literatúra', 508 | 'sv' => 'Litteratur', 509 | ), 510 | 'LS' => 511 | (object) array( 512 | 'en' => 'Living Sober', 513 | 'es' => 'Viviendo Sobrio', 514 | 'fr' => 'Vivre… Sans alcool', 515 | 'ja' => 'リビングソーバー', 516 | 'nl' => 'Sober leven', 517 | 'pt' => 'Viver Sóbrio', 518 | 'sk' => 'Triezvy život', 519 | 'sv' => 'Leva Nyktert', 520 | ), 521 | 'LT' => 522 | (object) array( 523 | 'en' => 'Lithuanian', 524 | 'es' => 'Lituano', 525 | 'fr' => 'Lituanien', 526 | 'ja' => 'リトアニア語', 527 | 'nl' => 'Litouws', 528 | 'pt' => 'Lituano', 529 | 'sk' => 'Litovské', 530 | 'sv' => 'Litauiska', 531 | ), 532 | 'M' => 533 | (object) array( 534 | 'en' => 'Men', 535 | 'es' => 'Hombres', 536 | 'fr' => 'Hommes', 537 | 'ja' => '男性', 538 | 'nl' => 'Mannen', 539 | 'pt' => 'Homens', 540 | 'sk' => 'Muži', 541 | 'sv' => 'Mansmöte', 542 | ), 543 | 'MED' => 544 | (object) array( 545 | 'en' => 'Meditation', 546 | 'es' => 'Meditación', 547 | 'fr' => 'Méditation', 548 | 'ja' => '黙想', 549 | 'nl' => 'Meditatie', 550 | 'pt' => 'Meditação', 551 | 'sk' => 'Meditácia', 552 | 'sv' => 'Meditationsmöte', 553 | ), 554 | 'ML' => 555 | (object) array( 556 | 'en' => 'Malayalam', 557 | 'es' => 'Malayalam', 558 | 'fr' => 'Malayalam', 559 | 'ja' => 'マラヤーラム語', 560 | 'nl' => 'Malayalam', 561 | 'pt' => 'Malaiala', 562 | 'sk' => 'Malajálamsky', 563 | 'sv' => 'Malayalam', 564 | ), 565 | 'MT' => 566 | (object) array( 567 | 'en' => 'Maltese', 568 | 'es' => 'Maltés', 569 | 'fr' => 'Maltais', 570 | 'ja' => 'マルタ語', 571 | 'nl' => 'Maltees', 572 | 'pt' => 'Maltês', 573 | 'sk' => 'Maltézske', 574 | 'sv' => 'Maltesiska', 575 | ), 576 | 'N' => 577 | (object) array( 578 | 'en' => 'Native American', 579 | 'es' => 'Nativo Americano', 580 | 'fr' => 'Autochtone', 581 | 'ja' => 'ネイティブアメリカン', 582 | 'nl' => 'Indiaan', 583 | 'pt' => 'Nativo Americano', 584 | 'sk' => 'Domorodí Američania', 585 | 'sv' => 'Ur-amerikanskt', 586 | ), 587 | 'NB' => 588 | (object) array( 589 | 'en' => 'Non-Binary', 590 | 'es' => 'No binario', 591 | 'fr' => 'Non binaire', 592 | 'ja' => 'ノンバイナリー', 593 | 'nl' => 'Niet-binair', 594 | 'pt' => 'Não binário', 595 | 'sk' => 'Nebinárne', 596 | 'sv' => 'Icke-binär', 597 | ), 598 | 'NDG' => 599 | (object) array( 600 | 'en' => 'Indigenous', 601 | 'es' => 'Indígena', 602 | 'fr' => 'Indigène', 603 | 'ja' => '先住民', 604 | 'nl' => 'Inheems', 605 | 'pt' => 'Indígena', 606 | 'sk' => 'Domorodé', 607 | 'sv' => 'Urfolkligt', 608 | ), 609 | 'NE' => 610 | (object) array( 611 | 'en' => 'Nepali', 612 | 'es' => 'Nepalí', 613 | 'fr' => 'Népalais', 614 | 'ja' => 'ネパール語', 615 | 'nl' => 'Nepalees', 616 | 'pt' => 'Nepalês', 617 | 'sk' => 'Nepálsky', 618 | 'sv' => 'Nepali', 619 | ), 620 | 'NL' => 621 | (object) array( 622 | 'en' => 'Dutch', 623 | 'es' => 'Holandés', 624 | 'fr' => 'Néerlandais', 625 | 'ja' => 'オランダ語', 626 | 'nl' => 'Nederlands', 627 | 'pt' => 'Holandês', 628 | 'sk' => 'Holandské', 629 | 'sv' => 'Holländska', 630 | ), 631 | 'NO' => 632 | (object) array( 633 | 'en' => 'Norwegian', 634 | 'es' => 'Noruego', 635 | 'fr' => 'Norvégien', 636 | 'ja' => 'ノルウェー語', 637 | 'nl' => 'Noors', 638 | 'pt' => 'Norueguês', 639 | 'sk' => 'Nórsky', 640 | 'sv' => 'Norska', 641 | ), 642 | 'O' => 643 | (object) array( 644 | 'en' => 'Open', 645 | 'es' => 'Abierta', 646 | 'fr' => 'Ouvert(e)', 647 | 'ja' => 'オープン', 648 | 'nl' => 'Open', 649 | 'pt' => 'Aberta', 650 | 'sk' => 'Otvorené', 651 | 'sv' => 'Öppet', 652 | ), 653 | 'OUT' => 654 | (object) array( 655 | 'en' => 'Outdoor', 656 | 'es' => 'Al aire libre', 657 | 'fr' => 'En plein air', 658 | 'ja' => 'アウトドア', 659 | 'nl' => 'Buiten', 660 | 'pt' => 'Ao ar livre', 661 | 'sk' => 'Vonkajšie', 662 | 'sv' => 'Utomhus', 663 | ), 664 | 'P' => 665 | (object) array( 666 | 'en' => 'Professionals', 667 | 'es' => 'Profesionales', 668 | 'fr' => 'Professionnels', 669 | 'ja' => '職業人', 670 | 'nl' => 'Professionals', 671 | 'pt' => 'Profissionais', 672 | 'sk' => 'Profesionáli', 673 | 'sv' => 'Professionella', 674 | ), 675 | 'POA' => 676 | (object) array( 677 | 'en' => 'Proof of Attendance', 678 | 'es' => 'Prueba de Asistencia', 679 | 'fr' => 'Preuve de Présence', 680 | 'ja' => '出席証明', 681 | 'nl' => 'Bewijs van Aanwezigheid', 682 | 'pt' => 'Comprovante de Presença', 683 | 'sk' => 'Doklad o účasti', 684 | 'sv' => 'Närvarobevis', 685 | ), 686 | 'POC' => 687 | (object) array( 688 | 'en' => 'People of Color', 689 | 'es' => 'Gente de color', 690 | 'fr' => 'Gens de couleur', 691 | 'ja' => '有色人種', 692 | 'nl' => 'Mensen van kleur', 693 | 'pt' => 'Pessoas de Côr', 694 | 'sk' => 'Farební ľudia', 695 | 'sv' => 'Färgade', 696 | ), 697 | 'POL' => 698 | (object) array( 699 | 'en' => 'Polish', 700 | 'es' => 'Polaco', 701 | 'fr' => 'Polonais', 702 | 'ja' => 'ポーランド語', 703 | 'nl' => 'Pools', 704 | 'pt' => 'Polaco', 705 | 'sk' => 'Poľské', 706 | 'sv' => 'Polska', 707 | ), 708 | 'POR' => 709 | (object) array( 710 | 'en' => 'Portuguese', 711 | 'es' => 'Portugués', 712 | 'fr' => 'Portugais', 713 | 'ja' => 'ポルトガル語', 714 | 'nl' => 'Portugees', 715 | 'pt' => 'Português', 716 | 'sk' => 'Portugalské', 717 | 'sv' => 'Portugisiska', 718 | ), 719 | 'PUN' => 720 | (object) array( 721 | 'en' => 'Punjabi', 722 | 'es' => 'Punjabi', 723 | 'fr' => 'Pendjabi', 724 | 'ja' => 'パンジャブ語', 725 | 'nl' => 'Punjabi', 726 | 'pt' => 'Punjabi', 727 | 'sk' => 'Pandžábske', 728 | 'sv' => 'Punjabi', 729 | ), 730 | 'RUS' => 731 | (object) array( 732 | 'en' => 'Russian', 733 | 'es' => 'Ruso', 734 | 'fr' => 'Russe', 735 | 'ja' => 'ロシア語', 736 | 'nl' => 'Russisch', 737 | 'pt' => 'Russo', 738 | 'sk' => 'Ruské', 739 | 'sv' => 'Ryska', 740 | ), 741 | 'S' => 742 | (object) array( 743 | 'en' => 'Spanish', 744 | 'es' => 'Español', 745 | 'fr' => 'Espagnol', 746 | 'ja' => 'スペイン語', 747 | 'nl' => 'Spaans', 748 | 'pt' => 'Espanhol', 749 | 'sk' => 'Španielské', 750 | 'sv' => 'Spanska', 751 | ), 752 | 'SEN' => 753 | (object) array( 754 | 'en' => 'Seniors', 755 | 'es' => 'Personas mayores', 756 | 'fr' => 'Séniors', 757 | 'ja' => 'シニア', 758 | 'nl' => 'Senioren', 759 | 'pt' => 'Séniores', 760 | 'sk' => 'Seniori', 761 | 'sv' => 'Seniorer', 762 | ), 763 | 'SK' => 764 | (object) array( 765 | 'en' => 'Slovak', 766 | 'es' => 'Eslovaco', 767 | 'fr' => 'Slovaque', 768 | 'ja' => 'スロバキア語', 769 | 'nl' => 'Slowaaks', 770 | 'pt' => 'Eslovaco', 771 | 'sk' => 'Slovenské', 772 | 'sv' => 'Slovakiska', 773 | ), 774 | 'SL' => 775 | (object) array( 776 | 'en' => 'Slovenian', 777 | 'es' => 'Esloveno', 778 | 'fr' => 'Slovène', 779 | 'ja' => 'スロベニア語', 780 | 'nl' => 'Sloveens', 781 | 'pt' => 'Esloveno', 782 | 'sk' => 'Slovinské', 783 | 'sv' => 'Slovenska', 784 | ), 785 | 'SM' => 786 | (object) array( 787 | 'en' => 'Smoking Permitted', 788 | 'es' => 'Se permite fumar', 789 | 'fr' => 'Permis de fumer', 790 | 'ja' => '喫煙可', 791 | 'nl' => 'Roken toegestaan', 792 | 'pt' => 'Permitido Fumar', 793 | 'sk' => 'Fajčenie povolené', 794 | 'sv' => 'Rökning Tillåten', 795 | ), 796 | 'SP' => 797 | (object) array( 798 | 'en' => 'Speaker', 799 | 'es' => 'Orador', 800 | 'fr' => 'Conférencier', 801 | 'ja' => 'スピーカー', 802 | 'nl' => 'Spreker', 803 | 'pt' => 'Partilhador', 804 | 'sk' => 'Spíker', 805 | 'sv' => 'Talare', 806 | ), 807 | 'ST' => 808 | (object) array( 809 | 'en' => 'Step Study', 810 | 'es' => 'Estudio de pasos', 811 | 'fr' => 'Sur les Étapes', 812 | 'ja' => 'ステップ', 813 | 'nl' => 'Stap studie', 814 | 'pt' => 'Estudo de Passos', 815 | 'sk' => 'Štúdium Krokov', 816 | 'sv' => 'Stegmöte', 817 | ), 818 | 'SV' => 819 | (object) array( 820 | 'en' => 'Swedish', 821 | 'es' => 'Sueco', 822 | 'fr' => 'Suédois', 823 | 'ja' => 'スウェーデン語', 824 | 'nl' => 'Zweeds', 825 | 'pt' => 'Sueco', 826 | 'sk' => 'Švédske', 827 | 'sv' => 'Svenska', 828 | ), 829 | 'T' => 830 | (object) array( 831 | 'en' => 'Transgender', 832 | 'es' => 'Transgénero', 833 | 'fr' => 'Transgenre', 834 | 'ja' => 'トランスジェンダー', 835 | 'nl' => 'Transgender', 836 | 'pt' => 'Transgénero', 837 | 'sk' => 'Transgender', 838 | 'sv' => 'Transpersoner', 839 | ), 840 | 'TC' => 841 | (object) array( 842 | 'en' => 'Location Temporarily Closed', 843 | 'es' => 'Ubicación temporalmente cerrada', 844 | 'fr' => 'Emplacement temporairement fermé', 845 | 'ja' => '一時的休止中', 846 | 'nl' => 'Locatie tijdelijk gesloten', 847 | 'pt' => 'Local Temporáriamente Encerrado', 848 | 'sk' => 'Miesto dočasne zatvorené', 849 | 'sv' => 'Tillfälligt Stängt', 850 | ), 851 | 'TH' => 852 | (object) array( 853 | 'en' => 'Thai', 854 | 'es' => 'Tailandés', 855 | 'fr' => 'Thaï', 856 | 'ja' => 'タイ語', 857 | 'nl' => 'Thais', 858 | 'pt' => 'Tailandês', 859 | 'sk' => 'Thajské', 860 | 'sv' => 'Thailändska', 861 | ), 862 | 'TL' => 863 | (object) array( 864 | 'en' => 'Tagalog', 865 | 'es' => 'Tagalo', 866 | 'fr' => 'Tagalog', 867 | 'ja' => 'タガログ語', 868 | 'nl' => 'Tagalog', 869 | 'pt' => 'Tagalo', 870 | 'sk' => 'Tagalské', 871 | 'sv' => 'Tagalog', 872 | ), 873 | 'TR' => 874 | (object) array( 875 | 'en' => 'Tradition Study', 876 | 'es' => 'Estudio de tradicion', 877 | 'fr' => 'Étude des Traditions', 878 | 'ja' => '伝統', 879 | 'nl' => 'Traditie Studie', 880 | 'pt' => 'Estudo de Tradições', 881 | 'sk' => 'Tradičné štúdium', 882 | 'sv' => 'Traditionsmöte', 883 | ), 884 | 'TUR' => 885 | (object) array( 886 | 'en' => 'Turkish', 887 | 'es' => 'Turco', 888 | 'fr' => 'Turc', 889 | 'ja' => 'トルコ語', 890 | 'nl' => 'Turks', 891 | 'pt' => 'Turco', 892 | 'sk' => 'Turecký', 893 | 'sv' => 'Turkiska', 894 | ), 895 | 'UK' => 896 | (object) array( 897 | 'en' => 'Ukrainian', 898 | 'es' => 'Ucraniano', 899 | 'fr' => 'Ukrainien', 900 | 'ja' => 'ウクライナ語', 901 | 'nl' => 'Oekraïens', 902 | 'pt' => 'Ucraniano', 903 | 'sk' => 'Ukrajinské', 904 | 'sv' => 'Ukrainska', 905 | ), 906 | 'W' => 907 | (object) array( 908 | 'en' => 'Women', 909 | 'es' => 'Mujer', 910 | 'fr' => 'Femmes', 911 | 'ja' => '女性', 912 | 'nl' => 'Vrouwen', 913 | 'pt' => 'Mulheres', 914 | 'sk' => 'Ženy', 915 | 'sv' => 'Kvinnomöte', 916 | ), 917 | 'X' => 918 | (object) array( 919 | 'en' => 'Wheelchair Access', 920 | 'es' => 'Acceso en silla de ruedas', 921 | 'fr' => 'Accès aux fauteuils roulants', 922 | 'ja' => '車いすアクセス', 923 | 'nl' => 'Toegankelijk voor rolstoelgebruikers', 924 | 'pt' => 'Acesso a Cadeiras de Rodas', 925 | 'sk' => 'Prístup pre vozíčkarov', 926 | 'sv' => 'Handikappanpassat', 927 | ), 928 | 'XB' => 929 | (object) array( 930 | 'en' => 'Wheelchair-Accessible Bathroom', 931 | 'es' => 'Baño accesible para sillas de ruedas', 932 | 'fr' => 'Toilettes accessibles aux fauteuils roulants', 933 | 'ja' => '車いす使用者用トイレ', 934 | 'nl' => 'Rolstoeltoegankelijke badkamer', 935 | 'pt' => 'WC com Acesso a Cadeiras de Rodas', 936 | 'sk' => 'Bezbariérová kúpeľňa', 937 | 'sv' => 'Handikappanpassad WC', 938 | ), 939 | 'XT' => 940 | (object) array( 941 | 'en' => 'Cross Talk Permitted', 942 | 'es' => 'Se permite opinar', 943 | 'fr' => 'Conversation croisée permise', 944 | 'ja' => 'クロストーク可能', 945 | 'nl' => 'Cross-sharen toegestaan', 946 | 'pt' => 'Prtilhas Cruzadas Permitidas', 947 | 'sk' => 'Cross Talk povolený', 948 | 'sv' => 'Kommentarer Tilltåtna', 949 | ), 950 | 'Y' => 951 | (object) array( 952 | 'en' => 'Young People', 953 | 'es' => 'Gente joven', 954 | 'fr' => 'Jeunes', 955 | 'ja' => 'ヤング', 956 | 'nl' => 'Jongeren', 957 | 'pt' => 'Jovens', 958 | 'sk' => 'Mladí ľudia', 959 | 'sv' => 'Young People', 960 | ), 961 | ); 962 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export const types = { 2 | "11": { 3 | en: "11th Step Meditation", 4 | es: "Meditación del Paso 11", 5 | fr: "Méditation sur la 11e Étape", 6 | ja: "ステップ11 黙想", 7 | nl: "Stap 11 meditatie", 8 | pt: "Meditação do 11º Passo", 9 | sk: "Meditácia 11. kroku", 10 | sv: "11th Stegs Meditation", 11 | }, 12 | "12x12": { 13 | en: "12 Steps & 12 Traditions", 14 | es: "12 Pasos y 12 Tradiciones", 15 | fr: "12 Étapes et 12 Traditions", 16 | ja: "12のステップと12の伝統", 17 | nl: "12 Stappen en 12 Tradities", 18 | pt: "12 Passos e 12 Tradições", 19 | sk: "12 Krokov & 12 Tradícií", 20 | sv: "12 Steg & 12 Traditioner", 21 | }, 22 | A: { 23 | en: "Secular", 24 | es: "Secular", 25 | fr: "Séculier", 26 | ja: "無宗教", 27 | nl: "Seculier", 28 | pt: "Secular", 29 | sk: "Svetské", 30 | sv: "Sekulärt", 31 | }, 32 | ABSI: { 33 | en: "As Bill Sees It", 34 | es: "Como lo ve Bill", 35 | fr: "Réflexions de Bill", 36 | ja: "ビルはこう思う", 37 | nl: "Zoals Bill het ziet", 38 | pt: "Na opinião de Bill", 39 | sk: "Ako to vidí Bill", 40 | sv: "Som Bill Ser Det", 41 | }, 42 | AF: { 43 | en: "Afrikaans", 44 | es: "Afrikáans", 45 | fr: "Afrikaans", 46 | ja: "アフリカーンス語", 47 | nl: "Afrikaans", 48 | pt: "Afrikaans", 49 | sk: "Afrikánčina", 50 | sv: "Afrikaans", 51 | }, 52 | AL: { 53 | en: "Concurrent with Alateen", 54 | es: "Concurrente con Alateen", 55 | fr: "En même temps qu’Alateen", 56 | ja: "アラティーンと同時進行", 57 | nl: "Gelijktijdig met Alateen", 58 | pt: "Em simultâneo com Alateen", 59 | sk: "Súbežne s Alateen", 60 | sv: "Tillsammans med Alateen", 61 | }, 62 | "AL-AN": { 63 | en: "Concurrent with Al-Anon", 64 | es: "Concurrente con Al-Anon", 65 | fr: "En même temps qu’Al-Anon", 66 | ja: "アラノンと同時進行", 67 | nl: "Gelijktijdig met Al-Anon", 68 | pt: "Em simultâneo com Al-Anon", 69 | sk: "Súbežne s Al-Anon", 70 | sv: "Tillsammans med Al-Anon", 71 | }, 72 | AM: { 73 | en: "Amharic", 74 | es: "Amárico", 75 | fr: "Amharique", 76 | ja: "アムハラ語", 77 | nl: "Amhaars", 78 | pt: "Amárico", 79 | sk: "Amharčina", 80 | sv: "Amhariska", 81 | }, 82 | AR: { 83 | en: "Arabic", 84 | es: "Árabe", 85 | fr: "Arabe", 86 | ja: "アラビア語", 87 | nl: "Arabisch", 88 | pt: "Árabe", 89 | sk: "Arabské", 90 | sv: "Arabiska", 91 | }, 92 | ASL: { 93 | en: "American Sign Language", 94 | es: "Lenguaje por señas", 95 | fr: "Langage des Signes", 96 | ja: "アメリカ手話", 97 | nl: "Amerikaanse gebaren taal", 98 | pt: "Língua Gestual Americana", 99 | sk: "Americký posunkový jazyk", 100 | sv: "Amerikanskt teckenspråk", 101 | }, 102 | B: { 103 | en: "Big Book", 104 | es: "Libro Grande", 105 | fr: "Gros Livre", 106 | ja: "ビッグブック", 107 | nl: "Big Book", 108 | pt: "Livro Azul", 109 | sk: "Veľká Kniha", 110 | sv: "Stora Boken", 111 | }, 112 | BA: { 113 | en: "Babysitting Available", 114 | es: "Guardería disponible", 115 | fr: "Garderie d’enfants disponible", 116 | ja: "ベビーシッターあり", 117 | nl: "Kinderopvang aanwezig", 118 | pt: "Babysitting disponível", 119 | sk: "Dostupné opatrovanie detí", 120 | sv: "Barnvakt Finns", 121 | }, 122 | BE: { 123 | en: "Newcomer", 124 | es: "Principiantes", 125 | fr: "Nouveau/nouvelle", 126 | ja: "ビギナーズ", 127 | nl: "Nieuwkomer", 128 | pt: "Recém-chegados", 129 | sk: "Nováčikovia", 130 | sv: "Nykomling", 131 | }, 132 | BG: { 133 | en: "Bulgarian", 134 | es: "Búlgaro", 135 | fr: "Bulgare", 136 | ja: "ブルガリア語", 137 | nl: "Bulgaars", 138 | pt: "Búlgaro", 139 | sk: "Bulharské", 140 | sv: "Bulgariska", 141 | }, 142 | BI: { 143 | en: "Bisexual", 144 | es: "Bisexual", 145 | fr: "Bisexuel", 146 | ja: "バイセクシャル", 147 | nl: "Biseksueel", 148 | pt: "Bisexual", 149 | sk: "Bisexuálne", 150 | sv: "Bisexuellt", 151 | }, 152 | BRK: { 153 | en: "Breakfast", 154 | es: "Desayuno", 155 | fr: "Petit déjeuner", 156 | ja: "朝食", 157 | nl: "Ontbijt", 158 | pt: "Pequeno-Almoço", 159 | sk: "Raňajky", 160 | sv: "Frukost", 161 | }, 162 | C: { 163 | en: "Closed", 164 | es: "Cerrada", 165 | fr: "Fermé", 166 | ja: "クローズド", 167 | nl: "Gesloten", 168 | pt: "Fechada", 169 | sk: "Uzatvorené", 170 | sv: "Slutet", 171 | }, 172 | CAN: { 173 | en: "Candlelight", 174 | es: "Luz de una vela", 175 | fr: "À la chandelle", 176 | ja: "キャンドル", 177 | nl: "Candlelight", 178 | pt: "Luz de Velas", 179 | sk: "Sviečky", 180 | sv: "Tända Ljus", 181 | }, 182 | CF: { 183 | en: "Child-Friendly", 184 | es: "Niño amigable", 185 | fr: "Enfants acceptés", 186 | ja: "お子さま歓迎", 187 | nl: "Kindvriendelijk", 188 | pt: "Amigável para Crianças", 189 | sk: "Priateľský k deťom", 190 | sv: "Barnvänligt", 191 | }, 192 | D: { 193 | en: "Discussion", 194 | es: "Discusión", 195 | fr: "Discussion", 196 | ja: "ディスカッション", 197 | nl: "Discussie", 198 | pt: "Discussão", 199 | sk: "Diskusia", 200 | sv: "Diskussion", 201 | }, 202 | DA: { 203 | en: "Danish", 204 | es: "Danés", 205 | fr: "Danois", 206 | ja: "デンマーク語", 207 | nl: "Deens", 208 | pt: "Dinamarquês", 209 | sk: "Dánsky", 210 | sv: "Danska", 211 | }, 212 | DB: { 213 | en: "Digital Basket", 214 | es: "Canasta digital", 215 | fr: "Panier numérique", 216 | ja: "電子献金", 217 | nl: "Digitale mand", 218 | pt: "Cesto Digital", 219 | sk: "Digitálny košík", 220 | sv: "Digital Korg", 221 | }, 222 | DD: { 223 | en: "Dual Diagnosis", 224 | es: "Diagnóstico dual", 225 | fr: "Double diagnostic", 226 | ja: "重複診断", 227 | nl: "Dubbele diagnose", 228 | pt: "Duplo Diagnóstico", 229 | sk: "Duálna diagnóza", 230 | sv: "Dubbel Diagnos", 231 | }, 232 | DE: { 233 | en: "German", 234 | es: "Alemán", 235 | fr: "Allemand", 236 | ja: "ドイツ語", 237 | nl: "Duits", 238 | pt: "Alemão", 239 | sk: "Nemecké", 240 | sv: "Tyska", 241 | }, 242 | DR: { 243 | en: "Daily Reflections", 244 | es: "Reflexiones Diarias", 245 | fr: "Réflexions quotidiennes", 246 | ja: "今日を新たに", 247 | nl: "Dagelijkse weerspiegelingen", 248 | pt: "Reflexões Diárias", 249 | sv: "Dagliga Reflektioner", 250 | sk: "Denné úvahy", 251 | }, 252 | EL: { 253 | en: "Greek", 254 | es: "Griego", 255 | fr: "Grec", 256 | ja: "ギリシャ語", 257 | nl: "Grieks", 258 | pt: "Grego", 259 | sk: "Grécke", 260 | sv: "Grekiska", 261 | }, 262 | EN: { 263 | en: "English", 264 | es: "Inglés", 265 | fr: "Anglais", 266 | ja: "英語", 267 | nl: "Engels", 268 | pt: "Inglês", 269 | sk: "Anglické", 270 | sv: "Engelska", 271 | }, 272 | FA: { 273 | en: "Persian", 274 | es: "Persa", 275 | fr: "Persan", 276 | ja: "ペルシア語", 277 | nl: "Perzisch", 278 | pt: "Persa", 279 | sk: "Perzské", 280 | sv: "Persiska", 281 | }, 282 | FI: { 283 | en: "Finnish", 284 | es: "Finlandés", 285 | fr: "Finlandais", 286 | ja: "フィンランド語", 287 | nl: "Fins", 288 | pt: "Finlandês", 289 | sk: "Fínčina", 290 | sv: "Finska", 291 | }, 292 | FF: { 293 | en: "Fragrance Free", 294 | es: "Sin fragancia", 295 | fr: "Sans parfum", 296 | ja: "香水なし", 297 | nl: "Geen parfum", 298 | pt: "Sem Perfumes", 299 | sk: "Bez vône", 300 | sv: "Parfym Fritt", 301 | }, 302 | FR: { 303 | en: "French", 304 | es: "Francés", 305 | fr: "Français", 306 | ja: "フランス語", 307 | nl: "Frans", 308 | pt: "Francês", 309 | sk: "Francúzsky", 310 | sv: "Franska", 311 | }, 312 | G: { 313 | en: "Gay", 314 | es: "Gay", 315 | fr: "Gai", 316 | ja: "ゲイ", 317 | nl: "Homo", 318 | pt: "Gay", 319 | sk: "Gay", 320 | sv: "Gay", 321 | }, 322 | GR: { 323 | en: "Grapevine", 324 | es: "La Viña", 325 | fr: "Grapevine", 326 | ja: "グレープバイン", 327 | nl: "Wijnstok", 328 | pt: "Grapevine", 329 | sk: "Grapevine", 330 | sv: "Grapevine", 331 | }, 332 | H: { 333 | en: "Birthday", 334 | es: "Cumpleaños", 335 | fr: "Anniversaire", 336 | ja: "バースデー", 337 | nl: "Verjaardag", 338 | pt: "Aniversário", 339 | sk: "Narodeniny", 340 | sv: "Födelsedag", 341 | }, 342 | HE: { 343 | en: "Hebrew", 344 | es: "Hebreo", 345 | fr: "Hébreu", 346 | ja: "ヘブライ語", 347 | nl: "Hebreeuws", 348 | pt: "Hebreu", 349 | sk: "Hebrejské", 350 | sv: "Hebreiska", 351 | }, 352 | HI: { 353 | en: "Hindi", 354 | es: "Hindi", 355 | fr: "Hindi", 356 | ja: "ヒンディー語", 357 | nl: "Hindi", 358 | pt: "Hindi", 359 | sk: "Hindi", 360 | sv: "Hindi", 361 | }, 362 | HR: { 363 | en: "Croatian", 364 | es: "Croata", 365 | fr: "Croate", 366 | ja: "クロアチア語", 367 | nl: "Kroatisch", 368 | pt: "Croata", 369 | sk: "Chorvátsky", 370 | sv: "Kroatiska", 371 | }, 372 | HU: { 373 | en: "Hungarian", 374 | es: "Húngaro", 375 | fr: "Hongrois", 376 | ja: "ハンガリー語", 377 | nl: "Hongaars", 378 | pt: "Hungaro", 379 | sk: "Maďarské", 380 | sv: "Ungerska", 381 | }, 382 | IS: { 383 | en: "Icelandic", 384 | es: "Islandés", 385 | fr: "Islandais", 386 | ja: "アイスランド語", 387 | nl: "IJslands", 388 | pt: "Islandês", 389 | sk: "Islanské", 390 | sv: "Isländska", 391 | }, 392 | ITA: { 393 | en: "Italian", 394 | es: "Italiano", 395 | fr: "Italien", 396 | ja: "イタリア語", 397 | nl: "Italiaans", 398 | pt: "Italiano", 399 | sk: "Taliansky", 400 | sv: "Italienska", 401 | }, 402 | JA: { 403 | en: "Japanese", 404 | es: "Japonés", 405 | fr: "Japonais", 406 | ja: "日本語", 407 | nl: "Japans", 408 | pt: "Japonês", 409 | sk: "Japonské", 410 | sv: "Japanska", 411 | }, 412 | KA: { 413 | en: "Georgian", 414 | es: "Georgiano", 415 | fr: "Géorgien", 416 | ja: "ジョージア語", 417 | nl: "Georgisch", 418 | pt: "Georgiano", 419 | sk: "Gruzínske", 420 | sv: "Georgiska", 421 | }, 422 | KOR: { 423 | en: "Korean", 424 | es: "Coreano", 425 | fr: "Coréen", 426 | ja: "韓国語", 427 | nl: "Koreaans", 428 | pt: "Coreano", 429 | sk: "Kórejske", 430 | sv: "Koreanska", 431 | }, 432 | L: { 433 | en: "Lesbian", 434 | es: "Lesbiana", 435 | fr: "Lesbienne", 436 | ja: "レズビアン", 437 | nl: "Lesbisch", 438 | pt: "Lésbica", 439 | sk: "Lesbické", 440 | sv: "Lesbiskt", 441 | }, 442 | LGBTQ: { 443 | en: "LGBTQ", 444 | es: "LGBTQ", 445 | fr: "LGBTQ", 446 | ja: "LGBTQ", 447 | nl: "LGBTQ", 448 | pt: "LGBTQ", 449 | sk: "LGBTQ", 450 | sv: "HBTQ", 451 | }, 452 | LIT: { 453 | en: "Literature", 454 | es: "Literatura", 455 | fr: "Publications", 456 | ja: "書籍", 457 | nl: "Literatuur", 458 | pt: "Literatura", 459 | sk: "Literatúra", 460 | sv: "Litteratur", 461 | }, 462 | LS: { 463 | en: "Living Sober", 464 | es: "Viviendo Sobrio", 465 | fr: "Vivre… Sans alcool", 466 | ja: "リビングソーバー", 467 | nl: "Sober leven", 468 | pt: "Viver Sóbrio", 469 | sk: "Triezvy život", 470 | sv: "Leva Nyktert", 471 | }, 472 | LT: { 473 | en: "Lithuanian", 474 | es: "Lituano", 475 | fr: "Lituanien", 476 | ja: "リトアニア語", 477 | nl: "Litouws", 478 | pt: "Lituano", 479 | sk: "Litovské", 480 | sv: "Litauiska", 481 | }, 482 | M: { 483 | en: "Men", 484 | es: "Hombres", 485 | fr: "Hommes", 486 | ja: "男性", 487 | nl: "Mannen", 488 | pt: "Homens", 489 | sk: "Muži", 490 | sv: "Mansmöte", 491 | }, 492 | MED: { 493 | en: "Meditation", 494 | es: "Meditación", 495 | fr: "Méditation", 496 | ja: "黙想", 497 | nl: "Meditatie", 498 | pt: "Meditação", 499 | sk: "Meditácia", 500 | sv: "Meditationsmöte", 501 | }, 502 | ML: { 503 | en: "Malayalam", 504 | es: "Malayalam", 505 | fr: "Malayalam", 506 | ja: "マラヤーラム語", 507 | nl: "Malayalam", 508 | pt: "Malaiala", 509 | sk: "Malajálamsky", 510 | sv: "Malayalam", 511 | }, 512 | MT: { 513 | en: "Maltese", 514 | es: "Maltés", 515 | fr: "Maltais", 516 | ja: "マルタ語", 517 | nl: "Maltees", 518 | pt: "Maltês", 519 | sk: "Maltézske", 520 | sv: "Maltesiska", 521 | }, 522 | N: { 523 | en: "Native American", 524 | es: "Nativo Americano", 525 | fr: "Autochtone", 526 | ja: "ネイティブアメリカン", 527 | nl: "Indiaan", 528 | pt: "Nativo Americano", 529 | sk: "Domorodí Američania", 530 | sv: "Ur-amerikanskt", 531 | }, 532 | NB: { 533 | en: "Non-Binary", 534 | es: "No binario", 535 | fr: "Non binaire", 536 | ja: "ノンバイナリー", 537 | nl: "Niet-binair", 538 | pt: "Não binário", 539 | sk: "Nebinárne", 540 | sv: "Icke-binär", 541 | }, 542 | NDG: { 543 | en: "Indigenous", 544 | es: "Indígena", 545 | fr: "Indigène", 546 | ja: "先住民", 547 | nl: "Inheems", 548 | pt: "Indígena", 549 | sk: "Domorodé", 550 | sv: "Urfolkligt", 551 | }, 552 | NE: { 553 | en: "Nepali", 554 | es: "Nepalí", 555 | fr: "Népalais", 556 | ja: "ネパール語", 557 | nl: "Nepalees", 558 | pt: "Nepalês", 559 | sk: "Nepálsky", 560 | sv: "Nepali", 561 | }, 562 | NL: { 563 | en: "Dutch", 564 | es: "Holandés", 565 | fr: "Néerlandais", 566 | ja: "オランダ語", 567 | nl: "Nederlands", 568 | pt: "Holandês", 569 | sk: "Holandské", 570 | sv: "Holländska", 571 | }, 572 | NO: { 573 | en: "Norwegian", 574 | es: "Noruego", 575 | fr: "Norvégien", 576 | ja: "ノルウェー語", 577 | nl: "Noors", 578 | pt: "Norueguês", 579 | sk: "Nórsky", 580 | sv: "Norska", 581 | }, 582 | O: { 583 | en: "Open", 584 | es: "Abierta", 585 | fr: "Ouvert(e)", 586 | ja: "オープン", 587 | nl: "Open", 588 | pt: "Aberta", 589 | sk: "Otvorené", 590 | sv: "Öppet", 591 | }, 592 | OUT: { 593 | en: "Outdoor", 594 | es: "Al aire libre", 595 | fr: "En plein air", 596 | ja: "アウトドア", 597 | nl: "Buiten", 598 | pt: "Ao ar livre", 599 | sk: "Vonkajšie", 600 | sv: "Utomhus", 601 | }, 602 | P: { 603 | en: "Professionals", 604 | es: "Profesionales", 605 | fr: "Professionnels", 606 | ja: "職業人", 607 | nl: "Professionals", 608 | pt: "Profissionais", 609 | sk: "Profesionáli", 610 | sv: "Professionella", 611 | }, 612 | POA: { 613 | en: "Proof of Attendance", 614 | es: "Prueba de Asistencia", 615 | fr: "Preuve de Présence", 616 | ja: "出席証明", 617 | nl: "Bewijs van Aanwezigheid", 618 | pt: "Comprovante de Presença", 619 | sk: "Doklad o účasti", 620 | sv: "Närvarobevis", 621 | }, 622 | POC: { 623 | en: "People of Color", 624 | es: "Gente de color", 625 | fr: "Gens de couleur", 626 | ja: "有色人種", 627 | nl: "Mensen van kleur", 628 | pt: "Pessoas de Côr", 629 | sk: "Farební ľudia", 630 | sv: "Färgade", 631 | }, 632 | POL: { 633 | en: "Polish", 634 | es: "Polaco", 635 | fr: "Polonais", 636 | ja: "ポーランド語", 637 | nl: "Pools", 638 | pt: "Polaco", 639 | sk: "Poľské", 640 | sv: "Polska", 641 | }, 642 | POR: { 643 | en: "Portuguese", 644 | es: "Portugués", 645 | fr: "Portugais", 646 | ja: "ポルトガル語", 647 | nl: "Portugees", 648 | pt: "Português", 649 | sk: "Portugalské", 650 | sv: "Portugisiska", 651 | }, 652 | PUN: { 653 | en: "Punjabi", 654 | es: "Punjabi", 655 | fr: "Pendjabi", 656 | ja: "パンジャブ語", 657 | nl: "Punjabi", 658 | pt: "Punjabi", 659 | sk: "Pandžábske", 660 | sv: "Punjabi", 661 | }, 662 | RUS: { 663 | en: "Russian", 664 | es: "Ruso", 665 | fr: "Russe", 666 | ja: "ロシア語", 667 | nl: "Russisch", 668 | pt: "Russo", 669 | sk: "Ruské", 670 | sv: "Ryska", 671 | }, 672 | S: { 673 | en: "Spanish", 674 | es: "Español", 675 | fr: "Espagnol", 676 | ja: "スペイン語", 677 | nl: "Spaans", 678 | pt: "Espanhol", 679 | sk: "Španielské", 680 | sv: "Spanska", 681 | }, 682 | SEN: { 683 | en: "Seniors", 684 | es: "Personas mayores", 685 | fr: "Séniors", 686 | ja: "シニア", 687 | nl: "Senioren", 688 | pt: "Séniores", 689 | sk: "Seniori", 690 | sv: "Seniorer", 691 | }, 692 | SK: { 693 | en: "Slovak", 694 | es: "Eslovaco", 695 | fr: "Slovaque", 696 | ja: "スロバキア語", 697 | nl: "Slowaaks", 698 | pt: "Eslovaco", 699 | sk: "Slovenské", 700 | sv: "Slovakiska", 701 | }, 702 | SL: { 703 | en: "Slovenian", 704 | es: "Esloveno", 705 | fr: "Slovène", 706 | ja: "スロベニア語", 707 | nl: "Sloveens", 708 | pt: "Esloveno", 709 | sk: "Slovinské", 710 | sv: "Slovenska", 711 | }, 712 | SM: { 713 | en: "Smoking Permitted", 714 | es: "Se permite fumar", 715 | fr: "Permis de fumer", 716 | ja: "喫煙可", 717 | nl: "Roken toegestaan", 718 | pt: "Permitido Fumar", 719 | sk: "Fajčenie povolené", 720 | sv: "Rökning Tillåten", 721 | }, 722 | SP: { 723 | en: "Speaker", 724 | es: "Orador", 725 | fr: "Conférencier", 726 | ja: "スピーカー", 727 | nl: "Spreker", 728 | pt: "Partilhador", 729 | sk: "Spíker", 730 | sv: "Talare", 731 | }, 732 | ST: { 733 | en: "Step Study", 734 | es: "Estudio de pasos", 735 | fr: "Sur les Étapes", 736 | ja: "ステップ", 737 | nl: "Stap studie", 738 | pt: "Estudo de Passos", 739 | sk: "Štúdium Krokov", 740 | sv: "Stegmöte", 741 | }, 742 | SV: { 743 | en: "Swedish", 744 | es: "Sueco", 745 | fr: "Suédois", 746 | ja: "スウェーデン語", 747 | nl: "Zweeds", 748 | pt: "Sueco", 749 | sk: "Švédske", 750 | sv: "Svenska", 751 | }, 752 | T: { 753 | en: "Transgender", 754 | es: "Transgénero", 755 | fr: "Transgenre", 756 | ja: "トランスジェンダー", 757 | nl: "Transgender", 758 | pt: "Transgénero", 759 | sk: "Transgender", 760 | sv: "Transpersoner", 761 | }, 762 | TC: { 763 | en: "Location Temporarily Closed", 764 | es: "Ubicación temporalmente cerrada", 765 | fr: "Emplacement temporairement fermé", 766 | ja: "一時的休止中", 767 | nl: "Locatie tijdelijk gesloten", 768 | pt: "Local Temporáriamente Encerrado", 769 | sk: "Miesto dočasne zatvorené", 770 | sv: "Tillfälligt Stängt", 771 | }, 772 | TH: { 773 | en: "Thai", 774 | es: "Tailandés", 775 | fr: "Thaï", 776 | ja: "タイ語", 777 | nl: "Thais", 778 | pt: "Tailandês", 779 | sk: "Thajské", 780 | sv: "Thailändska", 781 | }, 782 | TL: { 783 | en: "Tagalog", 784 | es: "Tagalo", 785 | fr: "Tagalog", 786 | ja: "タガログ語", 787 | nl: "Tagalog", 788 | pt: "Tagalo", 789 | sk: "Tagalské", 790 | sv: "Tagalog", 791 | }, 792 | TR: { 793 | en: "Tradition Study", 794 | es: "Estudio de tradicion", 795 | fr: "Étude des Traditions", 796 | ja: "伝統", 797 | nl: "Traditie Studie", 798 | pt: "Estudo de Tradições", 799 | sk: "Tradičné štúdium", 800 | sv: "Traditionsmöte", 801 | }, 802 | TUR: { 803 | en: "Turkish", 804 | es: "Turco", 805 | fr: "Turc", 806 | ja: "トルコ語", 807 | nl: "Turks", 808 | pt: "Turco", 809 | sk: "Turecký", 810 | sv: "Turkiska", 811 | }, 812 | UK: { 813 | en: "Ukrainian", 814 | es: "Ucraniano", 815 | fr: "Ukrainien", 816 | ja: "ウクライナ語", 817 | nl: "Oekraïens", 818 | pt: "Ucraniano", 819 | sk: "Ukrajinské", 820 | sv: "Ukrainska", 821 | }, 822 | W: { 823 | en: "Women", 824 | es: "Mujer", 825 | fr: "Femmes", 826 | ja: "女性", 827 | nl: "Vrouwen", 828 | pt: "Mulheres", 829 | sk: "Ženy", 830 | sv: "Kvinnomöte", 831 | }, 832 | X: { 833 | en: "Wheelchair Access", 834 | es: "Acceso en silla de ruedas", 835 | fr: "Accès aux fauteuils roulants", 836 | ja: "車いすアクセス", 837 | nl: "Toegankelijk voor rolstoelgebruikers", 838 | pt: "Acesso a Cadeiras de Rodas", 839 | sk: "Prístup pre vozíčkarov", 840 | sv: "Handikappanpassat", 841 | }, 842 | XB: { 843 | en: "Wheelchair-Accessible Bathroom", 844 | es: "Baño accesible para sillas de ruedas", 845 | fr: "Toilettes accessibles aux fauteuils roulants", 846 | ja: "車いす使用者用トイレ", 847 | nl: "Rolstoeltoegankelijke badkamer", 848 | pt: "WC com Acesso a Cadeiras de Rodas", 849 | sk: "Bezbariérová kúpeľňa", 850 | sv: "Handikappanpassad WC", 851 | }, 852 | XT: { 853 | en: "Cross Talk Permitted", 854 | es: "Se permite opinar", 855 | fr: "Conversation croisée permise", 856 | ja: "クロストーク可能", 857 | nl: "Cross-sharen toegestaan", 858 | pt: "Prtilhas Cruzadas Permitidas", 859 | sk: "Cross Talk povolený", 860 | sv: "Kommentarer Tilltåtna", 861 | }, 862 | Y: { 863 | en: "Young People", 864 | es: "Gente joven", 865 | fr: "Jeunes", 866 | ja: "ヤング", 867 | nl: "Jongeren", 868 | pt: "Jovens", 869 | sk: "Mladí ľudia", 870 | sv: "Young People", 871 | }, 872 | }; 873 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./lib", 7 | "strict": true 8 | }, 9 | "include": ["src"], 10 | "exclude": ["node_modules", "**/__tests__/*"] 11 | } 12 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:recommended", "tslint-config-prettier"] 3 | } 4 | --------------------------------------------------------------------------------