| 1 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | The base module provides a base :class:`Base` class for all objects that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | are tracked by Elodie. The Base class provides some base functionality used | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | by all the media types, but isn't itself used to represent anything. Its | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | sub-classes (:class:`~elodie.media.audio.Audio`, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | :class:`~elodie.media.photo.Photo`, :class:`~elodie.media.video.Video`, and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | :class:`~elodie.media.text.Text`) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | are used to represent the actual files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | .. moduleauthor:: Jaisen Mathai <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | import mimetypes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | import os | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | from datetime import datetime, timedelta | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | from pytz import timezone | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | from time import mktime | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | from tzwhere.tzwhere import tzwhere | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  | from elodie.config import load_config | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | try:        # Py3k compatibility | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     basestring | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | except NameError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     basestring = (bytes, str) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  | class Base(object): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     """The base class for all media objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     :param str source: The fully qualified path to the video file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     __name__ = 'Base' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     extensions = () | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     def __init__(self, source=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |         self.source = source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |         self.reset_cache() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     def format_metadata(self, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |         """Method to consistently return a populated metadata dictionary. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |         :returns: dict | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     def get_album(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         """Base method for getting an album | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         :returns: None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     def get_camera_make(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |     def get_camera_model(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     def get_date_taken_adjusted(self, date_taken, latitude, longitude): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |         """Returns date taken and adjust based on time zone if needed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |         Time zone conversion is based on a configurable value from config.ini. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |         :returns: int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |         config = load_config() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         # Check if use_location config is true and file has lat/lon | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |         # Else default to returning date_taken directly from file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         if( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             'Timezone' in config and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |             'use_location' in config['Timezone'] and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |             config['Timezone'].getboolean('use_location') is True and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |             latitude is not None and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |             longitude is not None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         ): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |             timezone_string = tzwhere().tzNameAt( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |                                 latitude, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |                                 longitude | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |                               ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |             date_taken_as_time = datetime.fromtimestamp(mktime(date_taken)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |             now_in_timezone = datetime.now(timezone(timezone_string)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |             seconds_offset = now_in_timezone.utcoffset().total_seconds() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |             adjusted_date_taken = date_taken_as_time - timedelta(seconds = seconds_offset) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |             return adjusted_date_taken.timetuple() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |         return date_taken | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     def get_coordinate(self, type): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     def get_extension(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         """Get the file extension as a lowercased string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         :returns: string or None for a non-video | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |         if(not self.is_valid()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |         source = self.source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         return os.path.splitext(source)[1][1:].lower() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |     def get_file_path(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |         """Get the full path to the video. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |         :returns: string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         return self.source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     def get_metadata(self, update_cache=False): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |         """Get a dictionary of metadata for any file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         All keys will be present and have a value of None if not obtained. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         :returns: dict or None for non-text files | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |         if(not self.is_valid()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |         if(isinstance(self.metadata, dict) and update_cache is False): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             return self.metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         source = self.source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |         self.metadata = { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             'date_taken': self.get_date_taken(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |             'camera_make': self.get_camera_make(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |             'camera_model': self.get_camera_model(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             'latitude': self.get_coordinate('latitude'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |             'longitude': self.get_coordinate('longitude'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |             'album': self.get_album(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |             'title': self.get_title(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |             'mime_type': self.get_mimetype(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             'original_name': self.get_original_name(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |             'base_name': os.path.splitext(os.path.basename(source))[0], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |             'extension': self.get_extension(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |             'directory_path': os.path.dirname(source) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         self.metadata['date_taken_adjusted'] = self.get_date_taken_adjusted( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |                                                 self.metadata['date_taken'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |                                                 self.metadata['latitude'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |                                                 self.metadata['longitude'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |                                                ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         return self.metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |     def get_mimetype(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |         """Get the mimetype of the file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |         :returns: str or None for unsupported files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |         if(not self.is_valid()): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |         source = self.source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         mimetype = mimetypes.guess_type(source) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |         if(mimetype is None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |         return mimetype[0] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |     def get_original_name(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         """Get the original name of the file from before it was imported. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |         Does not include the extension. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         Overridden by Media class for files with EXIF. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |         :returns: str or None for unsupported files. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |     def get_title(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |         """Base method for getting the title of a file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |         :returns: None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |     def is_valid(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |         """Check the file extension against valid file extensions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |         The list of valid file extensions come from self.extensions. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |         :returns: bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |         source = self.source | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |         return os.path.splitext(source)[1][1:].lower() in self.extensions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |     def reset_cache(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |         """Resets any internal cache | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |         self.metadata = None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |     def set_album(self, name): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |         """Base method for setting the album of a file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |         :returns: None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |     def set_album_from_folder(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         """Set the album attribute based on the leaf folder name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |         :returns: bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |         metadata = self.get_metadata() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |         # If this file has an album already set we do not overwrite EXIF | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |         if(not isinstance(metadata, dict) or metadata['album'] is not None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |             return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |         folder = os.path.basename(metadata['directory_path']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |         # If folder is empty we skip | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         if(len(folder) == 0): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |             return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |         self.set_album(folder) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |         return True | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |     def set_metadata_basename(self, new_basename): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |         """Update the basename attribute in the metadata dict for this instance. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |         This is used for when we update the EXIF title of a media file. Since | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |         that determines the name of a file if we update the title of a file | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |         more than once it appends to the file name. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |         i.e. 2015-12-31_00-00-00-my-first-title-my-second-title.jpg | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |         :param str new_basename: New basename of file (with the old title | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |             removed). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |         self.get_metadata() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |         self.metadata['base_name'] = new_basename | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |     def set_metadata(self, **kwargs): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |         """Method to manually update attributes in metadata. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |         :params dict kwargs: Named parameters to update. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |         metadata = self.get_metadata() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |         for key in kwargs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |             if(key in metadata): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |                 self.metadata[key] = kwargs[key] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |     def set_original_name(self): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |         """Stores the original file name into EXIF/metadata. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         :returns: bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |         return False | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |     @classmethod | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |     def get_class_by_file(cls, _file, classes): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |         """Static method to get a media object by file. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |         """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |         if not isinstance(_file, basestring) or not os.path.isfile(_file): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |             return None | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |         extension = os.path.splitext(_file)[1][1:].lower() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |         if len(extension) > 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |             for i in classes: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |                 if(extension in i.extensions): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |                     return i(_file) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         return None | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 266 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 267 |  |  |     @classmethod | 
            
                                                                        
                            
            
                                    
            
            
                | 268 |  |  |     def get_valid_extensions(cls): | 
            
                                                                        
                            
            
                                    
            
            
                | 269 |  |  |         """Static method to access static extensions variable. | 
            
                                                                        
                            
            
                                    
            
            
                | 270 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 271 |  |  |         :returns: tuple(str) | 
            
                                                                        
                            
            
                                    
            
            
                | 272 |  |  |         """ | 
            
                                                                        
                            
            
                                    
            
            
                | 273 |  |  |         return cls.extensions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  | def get_all_subclasses(cls=None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |     """Module method to get all subclasses of Base. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |     """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |     subclasses = set() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |     this_class = Base | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |     if cls is not None: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |         this_class = cls | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |     subclasses.add(this_class) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |     this_class_subclasses = this_class.__subclasses__() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |     for child_class in this_class_subclasses: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |         subclasses.update(get_all_subclasses(child_class)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 291 |  |  |     return subclasses | 
            
                                                        
            
                                    
            
            
                | 292 |  |  |  |