From f397d4f995451850f25080d0f84c77ba2aaa4f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 14 Jan 2015 14:52:23 +0100 Subject: Reorganize folders of graphics sources --- Graphics/android-icon-copier/.gitignore | 81 ++++++++++++ Graphics/android-icon-copier/LICENSE | 21 +++ Graphics/android-icon-copier/README.md | 109 ++++++++++++++++ Graphics/android-icon-copier/classic.py | 146 +++++++++++++++++++++ Graphics/android-icon-copier/copy | 162 ++++++++++++++++++++++++ Graphics/android-icon-copier/options.templ.json | 8 ++ 6 files changed, 527 insertions(+) create mode 100644 Graphics/android-icon-copier/.gitignore create mode 100644 Graphics/android-icon-copier/LICENSE create mode 100644 Graphics/android-icon-copier/README.md create mode 100644 Graphics/android-icon-copier/classic.py create mode 100755 Graphics/android-icon-copier/copy create mode 100644 Graphics/android-icon-copier/options.templ.json (limited to 'Graphics/android-icon-copier') diff --git a/Graphics/android-icon-copier/.gitignore b/Graphics/android-icon-copier/.gitignore new file mode 100644 index 000000000..3336b9152 --- /dev/null +++ b/Graphics/android-icon-copier/.gitignore @@ -0,0 +1,81 @@ +# Python + +*.py[cod] + +# Options +/options.json + +# Packages +*.egg +*.egg-info +/dist +/build +/eggs +/parts +/bin +/var +/sdist +/develop-eggs +/lib +/lib64 +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +### Generic + +*.log +*.sqlite? + +### Compiled binaries + +*.class +*.jar + +*.o +*.bin +*.a +*.lib +*.so +*.out + +*.obj +*.exe +*.dll +*.com + +### *nix OS / apps + +*.swp +*~ + +### Mac OS generated + +__MACOSX +Icon? +*.DS_Store +*.DS_Store? +._* +.Spotlight* +.Trashes + +### Windows generated + +ehthumbs.db +thumbs.db +Thumbs.db + diff --git a/Graphics/android-icon-copier/LICENSE b/Graphics/android-icon-copier/LICENSE new file mode 100644 index 000000000..4dc1175a5 --- /dev/null +++ b/Graphics/android-icon-copier/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Lucas Tan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Graphics/android-icon-copier/README.md b/Graphics/android-icon-copier/README.md new file mode 100644 index 000000000..3e12ae472 --- /dev/null +++ b/Graphics/android-icon-copier/README.md @@ -0,0 +1,109 @@ +[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--icon--copier-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1325) + +What is this +============ +A commandline tool to copy Android Material Design and FontAwesome icons to your + project folders: `drawable-ldpi`, `drawable-mdpi`, and etc. + +How it works +============ +It downloads from these repos: +- Material design: https://github.com/google/material-design-icons +- FontAwesome and "Classic" Android: https://github.com/svenkapudija/Android-Action-Bar-Icons + +Resolution supported +==================== + | l | m | h | xh | xxh | xxxh | +--------|---|---|---|----|-----|------| +FA | Y | Y | Y | Y | Y | - | +Classic | - | Y | Y | Y | Y | - | +Material| - | Y | Y | Y | Y | Y | + +Sizes supported +=============== +Material: 18, 24, 36, 48 dp. +FA and Classic: 32 dp only. + + +Usage +===== +
+Usage:
+Material      : ./copy {proj path} {category} {color} {icon name} [size]
+Classic and FA: ./copy {proj path} {fa/classic} {color} {icon name}
+
+ +`[]` denotes optional args. +**Args are case sensitive!** + +- `proj path`: Path to project folder relative to `base path`. + - `base path` can be defined in options file (see below). + - Auto-detects new or old project structure: `MyProject/src/main/res` or + `MyProject/res`. +- `category`: Either "classic", "fa", or Material category. +- `color`: Color of icon: Either "white", "grey" or "black". + - For Classic and FA, "white" refers to the Holo Dark theme (dark background). + "Grey" refers to the Holo Light theme. + - For Material, "grey" refers to grey600. +- `icon name`: Name of icon (must replace spaces and dashes with underscores). + - Without any prefix. Examples: FontAwesome "thumbs_up", Classic "search". +- `size` (integer): for Material only, Size in dp, defaults to 24 which is the + action bar icon size for material design. + +Examples +-------- +- `./copy MyProject maps white place` + - Downloads to `BasePath/MyProject/{src/main}/res/drawable-{m,h,xh,xxh,xxh}dpi +- `./copy MyProject maps white place 48` +- `./copy Path/to/MyProject fa grey thumbs_up` + +Windows users need to use `python copy` instead (I think). + +Filename mapping +================ +The tool also supports filename mapping of destination png files. (see options) +Mapping vars: + +- `cat`: category +- `name`: name as specified in commandline. +- `color`: color as specified: white, black, grey. +- `size`: integer only. +- `bg`: derived from color. black => bright, white => dark, grey => light. +- `bgSuffix`: "_dark" if bg is dark else empty string. + +Options file +============ +Named `options.json` in same dir. Sample: +```json +{ + "basePath": "~/Documents", + "filenameMap": { + "classic": "ic_action_{name}{bgSuffix}.png", + "fa": "ic_action_fa_{name}{bgSuffix}.png", + "material": "ic_{name}_{color}_{size}dp.png" + } +} +``` + +~ is expanded to the user home dir. + +`./copy Path/to/MyProject fa white thumbs_up` results in the +target filename of `ic_action_fa_thumbs_up_dark.png`. + +Installation +============ +- Python >= 2.7 (older or newer ver might work, you may try.) +- Python Requests package: `pip install requests` +- Git clone this repo or download the script. + +Icon cheatsheet +=============== +- Material: http://google.github.io/material-design-icons/ +- FA: http://fortawesome.github.io/Font-Awesome/icons/ (icons in 4.2 not supported) +- Classic: coming soon. + +License +======= +This project is under the MIT License. (see LICENSE) + +Please refer to the respective icon library for its licensing info. diff --git a/Graphics/android-icon-copier/classic.py b/Graphics/android-icon-copier/classic.py new file mode 100644 index 000000000..17ae1aac4 --- /dev/null +++ b/Graphics/android-icon-copier/classic.py @@ -0,0 +1,146 @@ +# Maps icon name to the dir name. +CLASSIC_MAP = { + 'about': '13_extra_actions_about', + 'accept': '01_core_accept', + 'accounts': '10_device_access_accounts', + 'add_alarm': '10_device_access_add_alarm', + 'add_group': '06_social_add_group', + 'add_person': '06_social_add_person', + 'add_to_queue': '09_media_add_to_queue', + 'airplane_mode_off': '10_device_access_airplane_mode_off', + 'airplane_mode_on': '10_device_access_airplane_mode_on', + 'alarms': '10_device_access_alarms', + 'attachment': '05_content_attachment', + 'back': '02_navigation_back', + 'backspace': '05_content_backspace', + 'bad': '03_rating_bad', + 'battery': '10_device_access_battery', + 'bightness_low': '10_device_access_bightness_low', + 'bluetooth': '10_device_access_bluetooth', + 'bluetooth_connected': '10_device_access_bluetooth_connected', + 'bluetooth_searching': '10_device_access_bluetooth_searching', + 'brightness_auto': '10_device_access_brightness_auto', + 'brightness_high': '10_device_access_brightness_high', + 'brightness_medium': '10_device_access_brightness_medium', + 'call': '01_core_call', + 'camera': '08_camera_camera', + 'cancel': '01_core_cancel', + 'cast': '09_media_cast', + 'cc_bcc': '06_social_cc_bcc', + 'chat': '06_social_chat', + 'cloud': '04_collections_cloud', + 'collapse': '02_navigation_collapse', + 'collection': '04_collections_collection', + 'computer': '11_hardware_computer', + 'copy': '01_core_copy', + 'crop': '08_camera_crop', + 'cut': '01_core_cut', + 'data_usage': '10_device_access_data_usage', + 'dial_pad': '10_device_access_dial_pad', + 'directions': '07_location_directions', + 'discard': '01_core_discard', + 'dock': '11_hardware_dock', + 'download': '09_media_download', + 'edit': '01_core_edit', + 'email': '05_content_email', + 'end_call': '10_device_access_end_call', + 'error': '12_alerts_and_states_error', + 'event': '05_content_event', + 'expand': '02_navigation_expand', + 'fast_forward': '09_media_fast_forward', + 'favorite': '03_rating_favorite', + 'flash_automatic': '08_camera_flash_automatic', + 'flash_off': '08_camera_flash_off', + 'flash_on': '08_camera_flash_on', + 'forward': '06_social_forward', + 'full_screen': '09_media_full_screen', + 'gamepad': '11_hardware_gamepad', + 'go_to_today': '04_collections_go_to_today', + 'good': '03_rating_good', + 'group': '06_social_group', + 'half_important': '03_rating_half_important', + 'headphones': '11_hardware_headphones', + 'headset': '11_hardware_headset', + 'help': '13_extra_actions_help', + 'import_export': '05_content_import_export', + 'important': '03_rating_important', + 'keyboard': '11_hardware_keyboard', + 'labels': '04_collections_labels', + 'location_found': '07_location_location_found', + 'location_off': '07_location_location_off', + 'location_searching': '07_location_location_searching', + 'make_available_offline': '09_media_make_available_offline', + 'map': '07_location_map', + 'merge': '05_content_merge', + 'mic': '08_camera_mic', + 'mic_muted': '08_camera_mic_muted', + 'mouse': '11_hardware_mouse', + 'network_cell': '10_device_access_network_cell', + 'network_wifi': '10_device_access_network_wifi', + 'new': '01_core_new', + 'new_account': '10_device_access_new_account', + 'new_attachment': '05_content_new_attachment', + 'new_email': '05_content_new_email', + 'new_event': '05_content_new_event', + 'new_label': '04_collections_new_label', + 'new_picture': '05_content_new_picture', + 'next': '09_media_next', + 'next_item': '02_navigation_next_item', + 'not_important': '03_rating_not_important', + 'not_secure': '10_device_access_not_secure', + 'overflow': '01_core_overflow', + 'paste': '01_core_paste', + 'pause': '09_media_pause', + 'pause_over_video': '09_media_pause_over_video', + 'person': '06_social_person', + 'phone': '11_hardware_phone', + 'picture': '05_content_picture', + 'place': '07_location_place', + 'play': '09_media_play', + 'play_over_video': '09_media_play_over_video', + 'previous': '09_media_previous', + 'previous_item': '02_navigation_previous_item', + 'read': '05_content_read', + 'refresh': '01_core_refresh', + 'remove': '01_core_remove', + 'repeat': '09_media_repeat', + 'replay': '09_media_replay', + 'reply': '06_social_reply', + 'reply_all': '06_social_reply_all', + 'return_from_full_screen': '09_media_return_from_full_screen', + 'rewind': '09_media_rewind', + 'ring_volume': '10_device_access_ring_volume', + 'rotate_left': '08_camera_rotate_left', + 'rotate_right': '08_camera_rotate_right', + 'save': '05_content_save', + 'screen_locked_to_landscape': '10_device_access_screen_locked_to_landscape', + 'screen_locked_to_portrait': '10_device_access_screen_locked_to_portrait', + 'screen_rotation': '10_device_access_screen_rotation', + 'sd_storage': '10_device_access_sd_storage', + 'search': '01_core_search', + 'secure': '10_device_access_secure', + 'select_all': '01_core_select_all', + 'send_now': '06_social_send_now', + 'settings': '13_extra_actions_settings', + 'share': '01_core_share', + 'shuffle': '09_media_shuffle', + 'slideshow': '09_media_slideshow', + 'sort_by_size': '04_collections_sort_by_size', + 'split': '05_content_split', + 'stop': '09_media_stop', + 'storage': '10_device_access_storage', + 'switch_camera': '08_camera_switch_camera', + 'switch_video': '08_camera_switch_video', + 'time': '10_device_access_time', + 'undo': '01_core_undo', + 'unread': '05_content_unread', + 'upload': '09_media_upload', + 'usb': '10_device_access_usb', + 'video': '08_camera_video', + 'view_as_grid': '04_collections_view_as_grid', + 'view_as_list': '04_collections_view_as_list', + 'volume_muted': '09_media_volume_muted', + 'volume_on': '09_media_volume_on', + 'warning': '12_alerts_and_states_warning', + 'web_site': '07_location_web_site', +} diff --git a/Graphics/android-icon-copier/copy b/Graphics/android-icon-copier/copy new file mode 100755 index 000000000..995a8789e --- /dev/null +++ b/Graphics/android-icon-copier/copy @@ -0,0 +1,162 @@ +#!/usr/bin/env python + +import os +import sys +import shutil +import requests +from os.path import expanduser +import classic + +resolutions = { + 'material': ("m", "h", "xh", "xxh", "xxxh"), + 'fa': ("l", "m", "h", "xh", "xxh"), + 'classic': ("m", "h", "xh", "xxh"), +} + + +class AppError(Exception): + pass + + +def make_filename(filename_format, cat, name, color, size): + args = { + 'cat': cat or '', + 'name': name, + 'color': color, + 'size': size, + } + bg = {'white': 'dark', 'grey': 'light', 'black': 'bright'}.get(color) or '' + bg_suffix = '_dark' if bg == 'dark' else '' + args['bgSuffix'] = bg_suffix + args['bg'] = bg + return filename_format.format(**args) + + +def download_url(url, target_path): + print("Downloading {} to {} ...".format(url, target_path)) + print("") + #r = requests.get(url, stream=True) + r = requests.get(url) + if r.status_code != 200: + raise AppError("url not found, perhaps invalid name, size or color") + with open(target_path, 'wb') as fd: + for chunk in r.iter_content(4096): + fd.write(chunk) + + +def make_material_icon_url(cat, res, name, color, size): + if color == 'grey': + color = 'grey600' + elif color not in ('white', 'black'): + raise AppError('invalid color') + return ('https://raw.githubusercontent.com/google/material-design-icons/master/' + + '{}/drawable-{}dpi/ic_{}_{}_{}dp.png').format(cat, res, name, color, size) + + +def make_fa_icon_url(res, name, color): + if color == 'white': + holo = 'dark' + elif color == 'grey': + holo = 'light' + else: + raise AppError('invalid color') + return ('https://raw.githubusercontent.com/svenkapudija/Android-Action-Bar-Icons/' + + 'master/Font Awesome/holo_{2}/ic_fa_{1}/drawable-{0}dpi/ic_fa_{1}.png').format(res, name, holo) + + +def make_classic_icon_url(res, name, color): + dirname = classic.CLASSIC_MAP.get(name) + if not dirname: + raise AppError('invalid name') + if color == 'white': + holo = 'dark' + elif color == 'grey': + holo = 'light' + else: + raise AppError('invalid color') + return ('https://raw.githubusercontent.com/svenkapudija/Android-Action-Bar-Icons/' + + 'master/Android Stock/holo_{2}/{3}/drawable-{0}dpi/ic_action_{1}.png').format(res, name, holo, dirname) + + +def make_target_path(base_path, proj, res, filename): + res_path1 = os.path.join(base_path, proj, 'src', 'main', 'res') + res_path2 = os.path.join(base_path, proj, 'res') + if os.path.isdir(res_path1): + res_path = res_path1 + elif os.path.isdir(res_path2): + res_path = res_path2 + else: + raise AppError('missing res dir') + res_specific_path = os.path.join(res_path, 'drawable-' + res + 'dpi') + try: + os.mkdir(res_specific_path) + except OSError: + pass + return os.path.join(res_specific_path, filename) + + +def do_material(options, proj_path, cat, name, color, size): + base_path = expanduser(options['basePath']) + filename_map = options['filenameMap'] + + for res in resolutions['material']: + filename = make_filename(filename_map['material'], cat, name, color, size) + target_path = make_target_path(base_path, proj_path, res, filename) + url = make_material_icon_url(cat, res, name, color, size) + download_url(url, target_path) + + +def do_classic_or_fa(options, proj_path, cat, name, color): + base_path = expanduser(options['basePath']) + filename_map = options['filenameMap'] + + for res in resolutions[cat]: + filename = make_filename(filename_map[cat], cat, name, color, size=32) + target_path = make_target_path(base_path, proj_path, res, filename) + url = globals()['make_' + cat + '_icon_url'](res, name, color) + download_url(url, target_path) + + +def print_usage(): + print("Usage:") + print("Material : ./copy [size]") + print("Classic & FA: ./copy ") + print("") + + +def main(): + import json + + if len(sys.argv) < 5: + print_usage() + return + + option_filename = 'options.json' + if not os.path.exists(option_filename): + option_filename = 'options.templ.json' + print("WARNING: using the template options file") + print("You should create your own options.json") + + with open(option_filename, 'r') as fd: + options = json.load(fd) + + proj_path = sys.argv[1] + cat = sys.argv[2] + color = sys.argv[3] + name = sys.argv[4] + + if cat == 'classic' or cat == 'fa': + do_classic_or_fa(options, proj_path, cat, name, color) + else: + size = sys.argv[5] if len(sys.argv) >= 6 else 0 + size = int(size) or 24 + do_material(options, proj_path, cat, name, color, size) + + +if __name__ == "__main__": + try: + main() + except AppError as e: + print(e.message) + + diff --git a/Graphics/android-icon-copier/options.templ.json b/Graphics/android-icon-copier/options.templ.json new file mode 100644 index 000000000..319d90f42 --- /dev/null +++ b/Graphics/android-icon-copier/options.templ.json @@ -0,0 +1,8 @@ +{ + "basePath": "~/Documents", + "filenameMap": { + "classic": "ic_action_{name}{bgSuffix}.png", + "fa": "ic_action_fa_{name}{bgSuffix}.png", + "material": "ic_{name}_{color}_{size}dp.png" + } +} -- cgit v1.2.3