o U7eW@sddlZddlZddlZddlmZddlmZddlmZeGdddej Z Gddde Z Gd d d ej Z Gd d d e Z dS) N)copy) sourceslist) get_distroc@seZdZdZeddZe         dddZddZed d Z e j d d Z ed d Z eddZ e j ddZ ddZ ddZddZddZdS) SourceEntryz single sources.list entry cKs||jdi|S)N) create_line)clskwargsrrH/usr/lib/python3/dist-packages/softwareproperties/extendedsourceslist.py create_entryszSourceEntry.create_entryNc Cs\|durd}|durtj}|durtj}|durg}|dur"g}|dr.d}|d}|r2dnd} g} |rC| dd|| durS| d | rNd nd d | } | r`d | d} |sd|}|rt|dd}|d|}d |}|rd |}| r| dsd| } n | d sd | } nd} | || d |d ||| S)aj Create a line from the given parts. The 'uri' parameter is mandatory; the rest will be filled with defaults if not set or if set to None. If 'dist' and 'suite' are both provided, 'suite' is ignored. If 'dist' includes a pocket and 'pocket' is provided, the 'pocket' parameter will replace the pocket in 'dist'. NF#Tz# zarch=,ztrusted=yesno z []-rz #) r binary_typecodename startswithlstripappendjoin partitionstrip) ruridisabledtypedistsuitepocketcomps architecturestrustedcommenthashmarkoptionsrrr rsL           (zSourceEntry.create_linecCszR|js|jr|j|jko|j|jkWS|j|jkoQ|j|jkoQt|jt|jkoQ|j|jkoQ|jd|jdkoQ|j |j koQ|j |j koQt|j t|j kWSt y\YdSw)- equal operator for two sources.list entries /F) invalidlinerrsetr#r$rrstripr r!r"AttributeErrorselfotherrrr __eq___s.         zSourceEntry.__eq__cCs|jddS)z_ Return the suite, without pocket This always returns the suite in lowercase. rr)rrlowerr0rrr r pszSourceEntry.suitecCs0|sdS|j}|r|d||_dS||_dSNr)_pocketr)r0 new_suiter!rrr r xs  cCs|jddS)z, Return the pocket, or if unset return None r)rrr4rrr r6szSourceEntry._pocketcCs|jpdS)zo Return the pocket, or if unset return 'release' This always returns the pocket in lowercase. release)r6r3r4rrr r!szSourceEntry.pocketcCs&|r |jd||_dS|j|_dSr5)r r)r0 new_pocketrrr r!s cCstt||jdS)z Copy this SourceEntry file)rstrr<r4rrr __copy__szSourceEntry.__copy__cKs*t|}|D] \}}t|||q|S)z8 Return copy of this SourceEntry with replaced field(s) )ritemssetattr)r0r entrykvrrr _replaceszSourceEntry._replacecCs |S)z debug helper )r=rr4rrr __str__s zSourceEntry.__str__c CsD|jr|jS|j|j|j|j|j|j|j|j |j |j d }|dS)z$ return the current entry as string ) rrrr r!r"r#r$r% ) r*r+rrrrr r6r"r#r$r%)r0r+rrr r=s  zSourceEntry.str) NNNNNNNNN)__name__ __module__ __qualname____doc__ classmethodr rr2propertyr setterr6r!r>rDrEr=rrrr rs<  B      rcsleZdZdZfddZddZddZdd d Zed d Z e j d d Z fddZ fddZ Z S)MergedSourceEntryau A SourceEntry representing one or more identical SourceEntries The SourceEntries this represents are identical except for the components they contain. This will contain all the contained entries' components. If all components are removed, this will still act as a normal SourceEntry without any components, but all corresponding real SourceEntries will be removed from the SourcesList. This may contain multiple SourceEntries that overlap components (e.g. two entries that both contain 'main' component), however once any changes are made to the set of comps, duplicates will be removed. cs8d|_tt|jt||jdd|_||_|g|_dS)NFr;T) _initializedsuperrN__init__r=r< _sourceslist_entries)r0rAr __class__rr rQs  zMergedSourceEntry.__init__cCs0t|tsdS|jr dS|jgd|jgdkS)z1 Check if this is equal to other, ignoring comps Fr") isinstancerr*rDr/rrr matchs zMergedSourceEntry.matchcCs|j|dS)a  Append entry This should be called only with an entry that is equal to us, besides comps. The new entry may contain comps already in other entries we contain, but any modification of our comps will remove all duplicate comps. N)rSrr0rArrr _appendszMergedSourceEntry._appendFcCstt|}t|j|ks|sdS|jD]&}t|j|@r:|t|j8}tt|j||_tt|j|B|_nqtt|j|B|_z|jd}Wn tyVYdSw|r|rt|j|kr|jtt|j|d}t||_|jj|d}|jj ||| ||S)a] Get single SourceEntry with comps This moves all the components into a single entry in our entries list, and returns that entry. If add is False, this will return None if we do not already contain all the requested comps; otherwise this adds any new comps. If isolate is False, the entry returned may contain more components than those requested in comps. If isolate is True, this moves any excess components into a new entry, located immediately after the returned entry. If any of the components already exist in one of our entries, it is used to move all the components to; otherwise the first entry in our list is used. Any of our entries that has all its components moved (thus has no components left) will be removed from our entries list and removed from our sourceslist. If called with no comps this will return our first SourceEntry. If we contain no SourceEntries (because we contain no components), this will return None if called with no comps. NrrV) r,rr"rSlistKeyErrorrDrRindexinsertrZ)r0r"addisolateenewenewirrr get_entrys.      zMergedSourceEntry.get_entrycCs(t}|jD] }|t|jO}qt|SN)r,rSr"r\)r0crbrrr r"s zMergedSourceEntry.compscCs|jsdStt|}|t|jkrdS|jD]}tt|j|@|_|t|j8}q|rP|js@t|g|_|jj|jdtt|jdj|B|jd_t|jD]}|jsg|j||jj|qUdS)Nr) rOr,rr"rSr\rRrremove)r0r"rbrrr r"s&     cs*|jD]}||qtt||dSrf)rS set_enabledrPrN)r0enabledrbrTrr ri7s  zMergedSourceEntry.set_enabledcs@|dks|ds|jD]}t|||q tt|||dS)Nr"_)rrSr@rPrN__setattribute__)r0namevaluerbrTrr rl<s z"MergedSourceEntry.__setattribute__)FF)rGrHrIrJrQrXrZrerLr"rMrirl __classcell__rrrTr rNs  =   rNcsfeZdZdZfddZddZddZdd Zd d Zd d dgdfddZ ddZ dddZ Z S) SourcesListz8 represents the full sources.list + sources.list.d file cst|_tt|dS)z" update the list of known entries N)r,_filesrPrprefreshr4rTrr rrFszSourcesList.refreshc 4t|j}|D]\fdd|D}q |S)) convenience method to get filtered list c"g|] }t| kr|qSrgetattr.0rbkeyrnrr O"z&SourcesList.filter..r\r?r0r lrrzr filterK zSourcesList.filtercc|jD]}|VqdS)zM simple iterator to go over self.list, returns SourceEntry types Nr\rYrrr __iter__Rs zSourcesList.__iter__cC t|jSz calculate len of self.list lenr\r4rrr __len__X zSourcesList.__len__c,tfddDotfddDS)r(cg|]}|vqSrrrxr1rr r|^z&SourcesList.__eq__..crrrrxr4rr r|_rallr/rr1r0r r2\zSourcesList.__eq__r NFc  Cs`|dkr|t|jkr|j|} nd} tj| ||||||d} t| |d} t|} | j| | dS)z+ Create a new entry and add it to our list rN)rrrrr"r%r#r;)before)rr\rrCollapsedSourcesList add_entry)r0rrrr"r%posr<r#rrr+ new_entry collapsedrrr r`as   zSourcesList.addcCsz.t|d}|D] }t||}|j|q Wdn1s!wY|j|WdSty?td|YdSw)z (re)load the current sources rNzcould not open file '%s' ) openrr\rrqr` Exceptionloggingwarning)r0r<fr+sourcerrr loadps   zSourcesList.loadc stdd|jD}|D]+td}fdd|jDD] }||qWdn1s2wYq |rW|j|D]ztWq?tt fySYq?w||_t j d}||vrd}t|d}||WddS1sywYdSdS) a* save the current sources By default, this will NOT remove any files that we no longer have entries for; those files will not be modified at all. If 'remove' is True, any files that we initially parsed, but no longer have any entries for, will be removed. css|]}|jVqdSrfr;rxrrr sz#SourcesList.save..wcsg|] }|jkr|qSrr;)rysfilenamerr r|sz$SourcesList.save..NzDir::Etc::sourcelistz## See sources.list(5) for more information, especialy # Remember that you can only use http, ftp or file URIs # CDROMs are managed through the apt-cdrom tool. ) r,r\rwriter=rqosrhOSErrorIOErrorapt_pkgconfig find_file)r0rhfilesrr sourcelistheaderrrr save{s0     "zSourcesList.save)F) rGrHrIrJrrrrrr2r`rrrorrrTr rpCs   rpc@steZdZdZdddZddZddZd d Zd d Zd dZ ddZ dddZ ddZ ddZ ddZddZdS)ra] collapsed version of SourcesList This provides a 'collapsed' view of a SourcesList. Each entry in our list is a MergedSourceEntry, representing real SourceEntry(s) from our backing SourcesList. Any changes to our MergedSourceEntries are reflected in our backing SourcesList, however direct changes to SourceEntries in our backing SourcesList are not reflected in our list until after our refresh() method is called. If you change any part of any MergedSourceEntry besides the comps, you must refresh the CollapsedSourcesList to pick up those changes. The 'files' kwarg may be used to restrict which lines of the backing SourcesList are included, by providing a list of filenames. This can be used, for example, to get a CollapsedSourcesList of only SourceEntry lines from the main sources.list file. NcCs$|pt|_||_g|_|dSrf)rprrqr\rr)r0rrrrr rQs  zCollapsedSourcesList.__init__ccr)zK iterator for self.list Returns MergedSourceEntry objects NrrYrrr rs zCollapsedSourcesList.__iter__cCrrrr4rrr rrzCollapsedSourcesList.__len__cr)r(crrrrxrrr r|rz/CollapsedSourcesList.__eq__..crrrrxr4rr r|rrr/rrr r2rzCollapsedSourcesList.__eq__cCs ||S)z* check if other is contained in this list ) has_entryr/rrr __contains__rz!CollapsedSourcesList.__contains__c rs)rtcrurrvrxrzrr r|r}z/CollapsedSourcesList.filter..r~rrrzr rrzCollapsedSourcesList.filtercCsbg|_|jD](}|jr|j|jvrq|jD]}||r#||n q|jt||jqdS)a- update only our list of MergedSourceEntries This updates only our list of MergedSourceEntries, our backing SourcesList is not updated. This should be called anytime our backing SourcesList is updated directly. This does not refresh our backing SourcesList. N)r\rrqr<rXrZrrN)r0rA mergedentryrrr rrs    zCollapsedSourcesList.refreshc Cs@|j|j d}t|j}d}d}|jD]}||r|}||r$|}|r*|r*nq|rB|r;t|j|} t| |_|j|ddS|r[|j|ddd} | | j|||S|ru||j jvru|j j |d} |j j | |n|r||j jvr|j j |} |j j | |n|j j ||j t ||j |S)a_ Add a new entry to the sources.list. This will try to find an existing entry, or an existing entry with the opposite 'disabled' state, to reuse. If an existing entry does not exist, new_entry is inserted. If either 'after' or 'before' are specified, and match an existing SourceEntry in our list, then new_entry will be inserted before or after the specified SourceEntry. If both 'after' and 'before' are provided, 'after' has precedence. If neither 'after' or 'before' are provided, new_entry is appended to the end of the list. )rNT)r`)r`rar[)rDrr,r"r\rXrerirrrr^r_rrN) r0rafterrinverser" match_entry match_inverserg inverse_comps new_inverse new_indexrrr rsB       zCollapsedSourcesList.add_entrycCs0||}|rtt|jt|j|_dSdS)a) Remove the specified entry form the sources.list This removes as much as possible of the entry. If the entry matches an existing entry in our list, but our entry contains more components, only the specified components will be removed from our list's entry. Similarly, if entry contains multiple components, this will remove those components from one or multiple entries, if needed. Any entries in our list that have all their components removed will be removed from our list. N)get_merged_entryr\r,r")r0rArgrrr remove_entry)s z!CollapsedSourcesList.remove_entrycCs||}|r ||jSdS)aR If we already contain new_entry, find and return it If new_entry is already contained in our list, with at least all the components in new_entry, this returns our existing entry. The returned entry may have more components than new_entry. If new_entry is not contained in our list, or we do not have all the components in new_entry, this returns None. This may combine multiple existing SourceEntry lines into a single SourceEntry line so it contains all the requested components. This returns a SourceEntry. N)rrer"r0rrgrrr re:s  zCollapsedSourcesList.get_entrycCs"|jD] }||r|SqdS)a This is similar to get_entry(), but we return the MergedSourceEntry This returns the MergedSourceEntry in our list that matches the new_entry. Note that this IGNORES any comps in the new_entry, so the returned MergedSourceEntry may have more or less comps than the new_entry. If we contain no match for the new_entry, return None. This method will never combine SourceEntry lines like the get_entry method sometimes does. This returns a MergedSourceEntry. N)r\rXrrrr rOs  z%CollapsedSourcesList.get_merged_entrycCs&||}|rt|jt|jkSdS)aW Check if we already contain new_entry If new_entry contains multiple components, they may be located in multiple lines; this only checks that all requested components, for exactly the SourceEntry that equals new_entry (besides comps), are included in our list. This will not change our list. F)rr,r"rrrr res zCollapsedSourcesList.has_entry)NN)rGrHrIrJrQrrr2rrrrrrrerrrrrr rs  ? r)rrrr aptsourcesraptsources.distrorinitrrNrpobjectrrrrr s   ]