def open_connection(self): """ This method tries to establish a connection with the Neo4j database, considering the parameters in the settings.py file in a first time (with the _try_connection() method), then, using default ones (with the _try_default_connection() method). """ connection_attempts = 0 response_connection = False response_default_connection = False while True: connection_attempts = connection_attempts + 1 response_connection = self._try_connection() if connection_attempts >= self.initial_connection_attempts_number: bulb_logger.error('''BULBConnectionError(""" The connection with the Neo4j database cannot be established, please check if : - your database is still running, - yours authentication credentials (uri, id, password) are valid in the settings.py file of your project. """)''') raise BULBConnectionError(""" The connection with the Neo4j database cannot be established, please check if : - your database is still running, - yours authentication credentials (uri, id, password) are valid in the settings.py file of your project. """) else: response_default_connection = self._try_default_connection() if response_connection or response_default_connection: break time.sleep(1)
def create_super_user(cls, **extrafields): extrafields.setdefault('is_super_user', True) extrafields.setdefault('is_staff_user', True) extrafields.setdefault('is_active_user', True) extrafields['password'] = _hash_password(extrafields['password']) is_super_user = extrafields.get('is_super_user') is_staff_user = extrafields.get('is_staff_user') if not is_super_user: bulb_logger.error( 'ValueError(\'A SuperUser must have "is_super_user = True".\')' ) raise ValueError('A SuperUser must have "is_super_user = True".') elif not is_staff_user: bulb_logger.error( 'ValueError(\'A SuperUser must have "is_staff_user = True".\')' ) raise ValueError('A SuperUser must have "is_staff_user = True".') else: new_super_user = User(**extrafields) return new_super_user
def save(self, session_key, session_dict, expire_date): if session_dict: s = self.__class__(session_key, self.encode(session_dict), expire_date) else: bulb_logger.error( 'BULBSessionDoesNotHaveData("The does\'nt have datas (\'session_dict\'), failed to save it.")') raise BULBSessionDoesNotHaveData("The does'nt have datas ('session_dict'), failed to save it.") return s
def delete_session(cls, session_key): response = cls.get(session_key=session_key) if response: gdbh.w_transaction("MATCH (s:Session {session_key:'%s'}) DETACH DELETE (s)" % session_key) else: bulb_logger.error( f'BULBSessionDoesNotExist("No session with session_key = \'{session_key}\'. So it cannot be deleted.")') raise BULBSessionDoesNotExist(f"No session with session_key = '{session_key}'. So it cannot be deleted.")
def check_and_set_transaction_type(transaction_type): if transaction_type not in ['WRITE', 'READ']: bulb_logger.error( f'BULBTransactionError("The current transaction\'s \'type\' must be defined on \'WRITE\', \'READ\' or None, not \'{transaction_type}\'.")' ) raise BULBTransactionError( f"The current transaction's 'type' must be defined on 'WRITE', 'READ' or None, not '{transaction_type}'." ) else: return transaction_type
def check_and_set_session_type(session_type): if session_type not in ['WRITE', 'READ', None]: bulb_logger.error( 'BULBSessionError("The current session\'s type must be defined on \'WRITE\', \'READ\' or None.")' ) raise BULBSessionError( "The current session's type must be defined on 'WRITE', 'READ' or None." ) else: return session_type
def __enter__(self): try: self.session = self.database_instance.driver.session( access_mode=self.type, bookmark=self.bookmarks) except AttributeError: bulb_logger.error( 'BULBConnectionError("Failed to establish connection with the database. Check yours given informations (uri, id and password).")' ) raise BULBConnectionError( "Failed to establish connection with the database. Check yours given informations (uri, id and password)." ) return self.session
def format_labels_to_cypher(labels_list, label_class_name): render = [] if not labels_list or labels_list is None: return label_class_name else: if isinstance(labels_list, list): for label in labels_list: render.append(label) return ':'.join(render) else: bulb_logger.error( 'BULBLabelsError("self.labels attribute must be a list.")') raise BULBLabelsError("self.labels attribute must be a list.")
def __enter__(self): if self.active_transaction is None: if self.type == 'WRITE': self.active_transaction = self.session.write_transaction( lambda tx, cypher_query: tx.run(cypher_query), self.cypher_query) return self.active_transaction.data() else: self.active_transaction = self.session.read_transaction( lambda tx, cypher_query: tx.run(cypher_query), self.cypher_query) return self.active_transaction.data() else: bulb_logger.error( 'BULBTransactionError("A transaction is already running...")') raise BULBTransactionError("A transaction is already running...")
def clean_email(self): email_regex = "^([a-zA-Z0-9_%+](\.|\-)?){,249}[a-zA-Z0-9_%]@([a-zA-Z0-9_%+]\-?){,249}[a-zA-Z0-9_%]\.[a-z]{2,}$" email = self.cleaned_data.get("email") if not email: bulb_logger.error( 'ValidationError("Please enter an email address.")') raise forms.ValidationError("Please enter an email address.", code="invalid") if not re.fullmatch(email_regex, email) or 6 > len(email) > 255: bulb_logger.error( 'ValidationError("Please enter a valid email address.")') raise forms.ValidationError("Please enter a valid email address.", code="invalid") return email.lower()
def clean_password(self): password_regex = "^(.*)?[૱┯┰┱┲❗►◄ĂăǕǖꞀ¤Ð¢℥Ω℧Kℶℷℸⅇ⅊⚌⚍⚎⚏⚭⚮⌀⏑⏒⏓⏔⏕⏖⏗⏘⏙⏠⏡⏦ᶀᶁᶂᶃᶄᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚᶸᵯᵰᵴᵶᵹᵼᵽᵾᵿ ⁁⁊ ⸜⸝¶¥£⅕⅙⅛⅔⅖⅗⅘⅜⅚⅐⅝↉⅓⅑⅒⅞←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇨⇩⇪⇧⇫⇬⇭⇮⇯⇰⇱⇲⇳⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿⟰⟱⟲⟳⟴⟵⟶⟷⟸⟹⟺⟻⟼⟽⟾⟿⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕⤖⤗⤘⤙⤚⤛⤜⤝⤞⤟⤠⤡⤢⤣⤤⤥⤦⤧⤨⤩⤪⤫⤬⤭⤮⤯⤰⤱⤲⤳⤴⤵⤶⤷⤸⤹⤺⤻⤼⤽⤾⤿⥀⥁⥂⥃⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑⥒⥓⥔⥕⥖⥗⥘⥙⥚⥛⥜⥝⥞⥟⥠⥡⥢⥣⥤⥥⥦⥧⥨⥩⥪⥫⥬⥭⥮⥯⥰⥱⥲⥳⥴⥵⥶⥷⥸⥹⥺⥻⥼⥽⥾⥿➔➘➙➚➛➜➝➞➝➞➟➠➡➢➣➤➥➦➧➨➩➩➪➫➬➭➮➯➱➲➳➴➵➶➷➸➹➺➻➼➽➾⬀⬁⬂⬃⬄⬅⬆⬇⬈⬉⬊⬋⬌⬍⬎⬏⬐⬑☇☈⏎⍃⍄⍅⍆⍇⍈⍐⍗⍌⍓⍍⍔⍏⍖♾⎌☊☋☌☍⌃⌄⌤⌅⌆⌇⚋⚊⌌⌍⌎⌏⌐⌑⌔⌕⌗⌙⌢⌣⌯⌬⌭⌮⌖⌰⌱⌲⌳⌴⌵⌶⌷⌸⌹⌺⌻⌼⍯⍰⌽⌾⌿⍀⍁⍂⍉⍊⍋⍎⍏⍑⍒⍕⍖⍘⍙⍚⍛⍜⍝⍞⍠⍟⍡⍢⍣⍤⍥⍨⍩⍦⍧⍬⍿⍪⍮⍫⍱⍲⍭⍳⍴⍵⍶⍷⍸⍹⍺⍼⍽⍾⎀⎁⎂⎃⎄⎅⎆⎉⎊⎋⎍⎎⎏⎐⎑⎒⎓⎔⎕⏣⌓⏥⏢⎖⎲⎳⎴⎵⎶⎸⎹⎺⎻⎼⎽⎾⎿⏀⏁⏂⏃⏄⏅⏆⏇⏈⏉⏉⏋⏌⏍⏐⏤⏚⏛Ⓝℰⓦ! ⌘«»‹›‘’“”„‚❝❞£¥€$¢¬¶@§®©™°×π±√‰Ω∞≈÷~≠¹²³½¼¾‐–—|⁄\[\]{}†‡…·•●⌥⌃⇧↩¡¿‽⁂∴∵◊※←→↑↓☜☞☝☟✔★☆♺☼☂☺☹☃✉✿✄✈✌✎♠♦♣♥♪♫♯♀♂αßÁáÀàÅåÄäÆæÇçÉéÈèÊêÍíÌìÎîÑñÓóÒòÔôÖöØøÚúÙùÜüŽž₳฿¢€₡¢₢₵₫££₤₣ƒ₲₭₥₦₱$$₮₩₩¥¥₴₰¤៛₪₯₠₧₨௹﷼㍐৲৳~ƻƼƽ¹¸¬¨ɂǁ¯Ɂǂ¡´°ꟾ¦}{|\.,·\]\)\[/_\¿º§\"\*\-\+\(!&%$¼¾½¶©®@ẟⱿ`Ȿ^꜠꜡ỻ'=:;<ꞌꞋ꞊ꞁꞈ꞉>?÷ℾℿ℔℩℉⅀℈þðÞµªꝋꜿꜾⱽⱺⱹⱷⱶⱵⱴⱱⱰⱦȶȴȣȢȡȝȜțȋȊȉȈǯǮǃǀƿƾƺƹƸƷƲưƪƣƢƟƛƖƕƍſỽ⸀⸁⸂⸃⸄⸅⸆⸇⸈⸉⸊⸋⸌⸍⸎⸏⸐⸑⸒⸔⸕▲▼◀▶◢◣◥◤△▽◿◺◹◸▴▾◂▸▵▿◃▹◁▷◅▻◬⟁⧋⧊⊿∆∇◭◮⧩⧨⌔⟐◇◆◈⬖⬗⬘⬙⬠⬡⎔⋄◊⧫⬢⬣▰▪◼▮◾▗▖■∎▃▄▅▆▇█▌▐▍▎▉▊▋❘❙❚▀▘▝▙▚▛▜▟▞░▒▓▂▁▬▔▫▯▭▱◽□◻▢⊞⊡⊟⊠▣▤▥▦⬚▧▨▩⬓◧⬒◨◩◪⬔⬕❏❐❑❒⧈◰◱◳◲◫⧇⧅⧄⍁⍂⟡⧉○◌◍◎◯❍◉⦾⊙⦿⊜⊖⊘⊚⊛⊝●⚫⦁◐◑◒◓◔◕⦶⦸◵◴◶◷⊕⊗⦇⦈⦉⦊❨❩⸨⸩◖◗❪❫❮❯❬❭❰❱⊏⊐⊑⊒◘◙◚◛◜◝◞◟◠◡⋒⋓⋐⋑╰╮╭╯⌒╳✕╱╲⧸⧹⌓◦❖✖✚✜⧓⧗⧑⧒⧖_⚊╴╼╾‐⁃ ‒\-–⎯—―╶╺╸─━┄┅┈┉╌╍═≣≡☰☱☲☳☴☵☶☷╵╷╹╻│▕▏┃┆┇┊╎┋╿╽┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╏║╔╒╓╕╖╗╚╘╙╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬⌞⌟⌜⌝⌊⌋⌉⌈⌋₯ἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾈᾉᾊᾋᾌᾍᾎᾏᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾞᾟᾠᾡᾢᾣᾤᾥᾦᾧᾨᾩᾪᾫᾬᾭᾮᾯᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆᾼ᾽ι᾿῀῁ῂῃῄῆῇῈΈῊΉῌ῍῎῏ῐῑῒΐῖῗῘῙῚΊ῝῞῟ῠῡῢΰῤῥῦῧῨῩῪΎῬ῭΅`ῲῳῴῶῷῸΌῺΏῼ´῾ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;΄΅Ά·ΈΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿⒶⓐ⒜ẠạẢảḀḁÂÃǍǎẤấẦầẨẩȂȃẪẫẬậÀÁẮắẰằẲẳẴẵẶặĀāĄąǞȀȁÅǺǻÄäǟǠǡâáåãàẚȦȧȺÅⱥÆæǼǢǣⱯꜲꜳꜸꜺⱭꜹꜻª℀⅍℁Ⓑⓑ⒝ḂḃḄḅḆḇƁɃƀƃƂƄƅℬⒸⓒ⒞ḈḉĆćĈĉĊċČčÇçƇƈȻȼℂ℃ℭƆ℅℆℄ꜾꜿⒹⓓ⒟ḊḋḌḍḎḏḐḑḒḓĎďƊƋƌƉĐđȡⅅⅆDZDzdzDŽDždžȸⒺⓔ⒠ḔḕḖḗḘḙḚḛḜḝẸẹẺẻẾếẼẽỀềỂểỄễỆệĒēĔĕĖėĘęĚěÈèÉéÊêËëȄȅȨȩȆȇƎⱸɆℇℯ℮ƐℰƏǝⱻɇⒻⓕ⒡ḞḟƑƒꜰℲⅎꟻℱ℻Ⓖⓖ⒢ƓḠḡĜĝĞğĠġĢģǤǥǦǧǴℊ⅁ǵⒽⓗ⒣ḢḣḤḥḦḧḨḩḪḫẖĤĥȞȟĦħⱧⱨꜦℍǶℏℎℋℌꜧⒾⓘ⒤ḬḭḮḯIJijìíîïÌÍÎÏĨĩĪīĬĭĮįıƗƚỺǏǐⅈⅉℹℑℐⒿⓙ⒥ĴĵȷⱼɈɉǰⓀⓚ⒦ḰḱḲḳḴḵĶķƘƙꝀꝁꝂꝃꝄꝅǨǩⱩⱪĸⓁⓛ⒧ḶḷḸḹḺḻḼḽĹĺĻļĽİľĿŀŁłỈỉỊịȽⱠꝈꝉⱡⱢꞁℒLJLjlj⅃⅂ℓȉȈȊȋⓂⓜ⒨ḾḿṀṁṂṃꟿꟽⱮƩƜℳⓃⓝ⒩ṄṅṆṇṈṉṊṋŃńŅņŇňǸǹŊƝñʼnÑȠƞŋNJNjnjȵℕ№ṌṍṎṏṐṑṒṓȪȫȬȭȮȯȰȱǪǫǬǭỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợƠơŌōŎŏŐőÒÓÔÕÖǑȌȍȎȏŒœØǾꝊǽǿℴ⍥⍤Ⓞⓞ⒪òóôõöǒøꝎꝏⓅⓟ⒫℗ṔṕṖṗƤƥⱣℙǷꟼ℘Ⓠⓠ⒬Ɋɋℚ℺ȹⓇⓡ⒭ŔŕŖŗŘřṘṙṚṛṜṝṞṟȐȑȒȓɍɌƦⱤ℞Ꝛꝛℜℛ℟ℝⓈⓢ⒮ṠṡṢṣṤṥṦṧṨṩŚśŜŝŞşŠšȘșȿꜱƧƨẞßẛẜẝ℠Ⓣⓣ⒯ṪṫṬṭṮṯṰṱŢţŤťŦŧƬƮẗȚȾƫƭțⱦȶ℡™Ⓤⓤ⒰ṲṳṴṵṶṷṸṹṺṻỤỦủỨỪụứỬửừữỮỰựŨũŪūŬŭŮůŰűǙǚǗǘǛǜŲųǓǔȔȕÛûȖȗÙùÜüƯúɄưƲƱⓋⓥ⒱ṼṽṾṿỼɅ℣ⱱⱴⱽⓌⓦ⒲ẀẁẂẃẄẅẆẇẈẉŴŵẘⱲⱳⓍⓧ⒳ẊẋẌẍℵ×Ⓨⓨ⒴ẎẏỾỿẙỲỳỴỵỶỷỸỹŶŷƳƴŸÿÝýɎɏȲƔ⅄ȳℽⓏⓩ⒵ẐẑẒẓẔẕŹźŻżŽžȤȥⱫⱬƵƶɀℨℤ⟀⟁⟂⟃⟄⟇⟈⟉⟊⟐⟑⟒⟓⟔⟕⟖⟗⟘⟙⟚⟛⟜⟝⟞⟟⟠⟡⟢⟣⟤⟥⟦⟧⟨⟩⟪⟫⦀⦁⦂⦃⦄⦅⦆⦇⦈⦉⦊⦋⦌⦍⦎⦏⦐⦑⦒⦓⦔⦕⦖⦗⦘⦙⦚⦛⦜⦝⦞⦟⦠⦡⦢⦣⦤⦥⦦⦧⦨⦩⦪⦫⦬⦭⦮⦯⦰⦱⦲⦳⦴⦵⦶⦷⦸⦹⦺⦻⦼⦽⦾⦿⧀⧁⧂⧃⧄⧅⧆⧇⧈⧉⧊⧋⧌⧍⧎⧏⧐⧑⧒⧓⧔⧕⧖⧗⧘⧙⧚⧛⧜⧝⧞⧟⧡⧢⧣⧤⧥⧦⧧⧨⧩⧪⧫⧬⧭⧮⧯⧰⧱⧲⧳⧴⧵⧶⧷⧸⧹⧺⧻⧼⧽⧾⧿∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿✕✖✚◀▶❝❞★☆☼☂☺☹✄✈✌✎♪♫☀☁☔⚡❆☽☾✆✔☯☮☠⚑☬✄✏♰✡✰✺⚢⚣♕♛♚♬ⓐⓑⓒⓓ↺↻⇖⇗⇘⇙⟵⟷⟶⤴⤵⤶⤷➫➬€₤$₩₪⟁⟐◆⎔░▢⊡▩⟡◎◵⊗❖ΩβΦΣΞ⟁⦻⧉⧭⧴∞≌⊕⋍⋰⋱✖⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾ᴕ⸨⸩❪❫⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⓪①②③④⑤⑥⑦⑧⑨⑩➀➁➂➃➄➅➆➇➈➉⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⓿❶❷❸❹❺❻❼❽❾❿➊➋➌➍➎➏➐➑➒➓⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇ᶅᶛᶜᶝᶞᶟᶠᶡᶢᶣᶤᶥᶦᶧᶨᶩᶪᶫᶬᶭᶮᶯᶰᶱᶲᶳᶴᶵᶶᶷᶹᶺᶻᶼᶽᶾᶿᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᴬᴭᴮᴯᴰᴱᴲᴳᴴᴵᴶᴷᴸᴹᴺᴻᴼᴽᴾᴿᵀᵁᵂᵃᵄᵅᵆᵇᵈᵉᵊᵋᵌᵍᵎᵏᵐᵑᵒᵓᵔᵕᵖᵗᵘᵙᵚᵛᵜᵝᵞᵟᵠᵡᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵱᵲᵳᵵᵷᵸᵺᵻ ᷋ ᷌ ᷍ ᷎ ᷏ ᷓ ᷔ ᷕ ᷖ ᷗ ᷘ ᷙ ᷛ ᷜ ᷝ ᷞ ᷟ ᷠ ᷡ ᷢ ᷣ ᷤ ᷥ ᷦ‘’‛‚“”„‟«»‹›Ꞌ\"❛❜❝❞<>@‧¨․꞉:⁚⁝⁞‥…⁖⸪⸬⸫⸭⁛⁘⁙⁏;⦂⁃‐ ‒\-–⎯—―_⁓⸛⸞⸟ⸯ¬/\⁄\⁄|⎜¦‖‗†‡·•⸰°‣⁒%‰‱&⅋§÷\+±=꞊′″‴⁗‵‶‷‸\*⁑⁎⁕※⁜⁂!‼¡?¿⸮⁇⁉⁈‽⸘¼½¾²³©®™℠℻℅℁⅍℄¶⁋❡⁌⁍⸖⸗⸚⸓\(\)\[\]{}⸨⸩❨❩❪❫⸦⸧❬❭❮❯❰❱❴❵❲❳⦗⦘⁅⁆〈〉⏜⏝⏞⏟⸡⸠⸢⸣⸤⸥⎡⎤⎣⎦⎨⎬⌠⌡⎛⎠⎝⎞⁀⁔‿⁐‾⎟⎢⎥⎪ꞁ⎮⎧⎫⎩⎭⎰⎱✈☀☼☁☂☔⚡❄❅❆☃☉☄★☆☽☾⌛⌚☇☈⌂⌁✆☎☏☑✓✔⎷⍻✖✗✘☒✕☓☕♿✌☚☛☜☝☞☟☹☺☻☯⚘☮✝⚰⚱⚠☠☢⚔⚓⎈⚒⚑⚐☡❂⚕⚖⚗✇☣⚙☤⚚⚛⚜☥☦☧☨☩†☪☫☬☭✁✂✃✄✍✎✏✐✑✒✉✙✚✜✛♰♱✞✟✠✡☸✢✣✤✥✦✧✩✪✫✬✭✮✯✰✲✱✳✴✵✶✷✸✹✺✻✼✽✾❀✿❁❃❇❈❉❊❋⁕☘❦❧☙❢❣♀♂⚢⚣⚤⚦⚧⚨⚩☿♁⚯♔♕♖♗♘♙♚♛♜♝♞♟☖☗♠♣♦♥❤❥♡♢♤♧⚀⚁⚂⚃⚄⚅⚇⚆⚈⚉♨♩♪♫♬♭♮♯⌨⏏⎗⎘⎙⎚⌥⎇⌘⌦⌫⌧♲♳♴♵♶♷♸♹♺♻♼♽⁌⁍⎌⌇⌲⍝⍟⍣⍤⍥⍨⍩⎋♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓⏚⏛| | | || | | | | ||](.*)?$" password = self.cleaned_data.get("password") if not password: bulb_logger.error('ValidationError("Please enter a password."') raise forms.ValidationError("Please enter a password.", code="invalid") if not re.fullmatch(password_regex, password) or not re.fullmatch( "^(.*)?\d(.*)?$", password) or 10 > len(password) > 255: bulb_logger.error( 'ValidationError("Please enter a valid password."') raise forms.ValidationError("Please enter a valid password.", code="invalid") return password
def static_content(path): if settings.DEBUG or not settings.BULB_USE_SFTP: return urljoin(settings.STATIC_URL, quote(path)) else: pull_url = settings.BULB_SFTP_PULL_URL if pull_url is not None: src_url = pull_url + "/staticfiles/content/" return urljoin(src_url, quote(path)) else: bulb_logger.error( 'BULBStaticTemplateTagsError("To use the \'{% static_content %}\' tag you must define the BULB_SFTP_PULL_URL variable in your \'settings.py\' file.")' ) raise BULBStaticTemplateTagsError( "To use the '{% static_content %}' tag you must define the BULB_SFTP_PULL_URL variable in your 'settings.py' file." )
def static_bundled_src(path): if settings.DEBUG: return urljoin(os.path.join(BASE_DIR, "bundled_staticfiles"), quote(path)) else: pull_url = settings.BULB_SFTP_PULL_URL if pull_url is not None: src_url = pull_url + "/staticfiles/bundled_src/" return urljoin(src_url, quote(path)) else: bulb_logger.error( 'BULBStaticTemplateTagsError("To use the \'{% static_bundle_src %}\' tag you must define the BULB_SFTP_PULL_URL variable in your \'settings.py\' file.")' ) raise BULBStaticTemplateTagsError( "To use the '{% static_bundle_src %}' tag you must define the BULB_SFTP_PULL_URL variable in your 'settings.py' file." )
def get(cls, uuid=None, email=None, email_confirmation_key=None, order_by=None, limit=None, skip=None, desc=False, only=None, filter=None, distinct=False, handmade=None, return_query=False): """ This method allow the retrieving of User (or of one of its children classes) instances. :param email (required if there is neither uuid nor email_confirmation_key) : The email of a user to get an unique user instance. :param uuid (required if there is neither email nor email_confirmation_key) : The Universal Unique Identifier of a node to get an unique instance. :param email_confirmation_key (required if there is neither email nor uuid) : The confirmation key for the email validation part. :param order_by (optional, default=None) : Must be the name of the property with which the returned datas will be sorted. Examples : "datetime", "first_name", etc... :param limit (optional, default=None) : Must be an integer. This parameter defines the number of returned elements. :param skip (optional, default=None) : Must be an integer. This parameter defines the number of skipped elements. For example if self.skip = 3, the 3 first returned elements will be skipped. :param desc (optional, default=False) : Must be a boolean. If it is False the elements will be returned in an increasing order, but it is True, they will be returned in a descending order. :param only (optional, default=None) : Must be a list of field_names. If this parameter is filled, the return will not be Node instances, but a dict with "only" the mentioned fields. :param filter (optional, default=None) : Must be Q statement. You must use the Q class stored in bulb.db Example: Q(name__contains="al") | Q(age__year__lte=8) :param distinct (optional, default=False) : Must be a boolean. If it is True, the returned list will be only composed with unique elements. :param handmade: If this param is filled, no other must be filled. With 'handmade', you can insert your own get query and the function will transform the objects returned by the database into Python instance of this class. WARNING : Please consider using the gdbh.r_transaction() method (imported from bulb.db) if your request no returns full Neo4j objects but a list of properties. Examples : ❌ : MATCH (u) RETURN u.first_name, u.last_name ✅ : MATCH (u) RETURN u In addition, note that the RETURN must absolutely be named 'u' like "user". :param return_query (optional, default=False) : Must be a boolean. If true, the method will return the cypher query. :return: If uuid is None, a list will be returned. Else it will be a unique instance. """ if handmade is None: where_statement = "" property_statement = "" order_by_statement = "" limit_statement = "" skip_statement = "" desc_statement = "" # Build the property_statement. if uuid is not None and email is not None: property_statement = "{uuid:'%s', email:'%s'}" % (uuid, email) elif uuid is not None: property_statement = "{uuid:'%s'}" % uuid elif email is not None: property_statement = "{email:'%s'}" % email elif email_confirmation_key is not None: property_statement = "{email_confirmation_key:'%s'}" % email_confirmation_key # Build the match_statement. cyher_labels = node_models.DatabaseNode.format_labels_to_cypher( cls._get_labels()) match_statement = f"MATCH (u:{cyher_labels} {property_statement})" # Build the where statement. if filter is not None: # where_statement = "WHERE " + filter #removed to fix if not filter[0] != "n": where_statement = "WHERE " + filter else: where_statement = filter where_statement = where_statement.replace("n.", "u.") # Build the with_statement. with_statement = "WITH u" # Build order_by statements. if order_by is not None: order_by_statement = f"ORDER BY u.{order_by}" # Build return_statement statements. if not only: if not distinct: return_statement = "RETURN (u)" else: return_statement = "RETURN DISTINCT (u)" else: only_statement_list = [] for element in only: only_statement_list.append(f"u.{element}") only_statement = ", ".join(only_statement_list) if not distinct: return_statement = f"RETURN {only_statement}" else: return_statement = f"RETURN DISTINCT {only_statement}" # Build limit_statement. if limit is not None: if not isinstance(limit, str) and not isinstance(limit, int): bulb_logger.error( f'BULBNodeError("The \'limit\' parameter of the get() method of {cls.__name__} must be a string or an integer.")' ) raise BULBNodeError( f"The 'limit' parameter of the get() method of {cls.__name__} must be a string or an integer." ) else: limit_statement = f"LIMIT {limit}" # Build skip_statement and add its required variable. if skip is not None: if not isinstance(skip, str) and not isinstance(skip, int): bulb_logger.error( f'BULBNodeError("The \'skip\' parameter of the get() method of {cls.__name__} must be a string or an integer.")' ) raise BULBNodeError( f"The 'skip' parameter of the get() method of {cls.__name__} must be a string or an integer." ) else: skip_statement = f"SKIP {skip}" # Build desc_statement. if not isinstance(desc, bool): bulb_logger.error( f'BULBNodeError("The \'desc\' parameter of the get() method of {cls.__name__} must be a boolean.")' ) raise BULBNodeError( f"The 'desc' parameter of the get() method of {cls.__name__} must be a boolean." ) else: if desc is True: desc_statement = "DESC" request_statement = """ %s %s %s %s %s %s %s %s """ % (match_statement, where_statement, with_statement, order_by_statement, desc_statement, skip_statement, limit_statement, return_statement) if return_query is False: response = gdbh.r_transaction(request_statement) if response: if only is None: fake_instances_list = [] for user_object in response: fake_instances_list.append( cls.build_fake_instance( user_object["u"], forced_fake_instance_class=cls)) if uuid is not None or email is not None or email_confirmation_key is not None: return fake_instances_list[0] else: return fake_instances_list else: return response else: if uuid is not None or email is not None or email_confirmation_key is not None: if settings.BULB_ANONYMOUSUSER_NODE_MODEL_FILE: # TODO : This line is maybe useless, check it. AnonymousUser_node_model = get_anonymoususer_node_model( ) return AnonymousUser_node_model() else: return None else: return request_statement else: response = gdbh.r_transaction(handmade) fake_instances_list = [] for node_object in response: fake_instances_list.append( cls.build_fake_instance(node_object["u"], forced_fake_instance_class=cls)) return fake_instances_list
def set_password(self, new_password): bulb_logger.error( f'NotImplementedError("bulb doesn\'t provide a DB representation for AnonymousUser.")' ) raise NotImplementedError( "bulb doesn't provide a DB representation for AnonymousUser.")
def delete(self): bulb_logger.error( f'NotImplementedError("bulb doesn\'t provide a DB representation for AnonymousUser.")' ) raise NotImplementedError( "bulb doesn't provide a DB representation for AnonymousUser.")
def update(self, user_property, new_user_property_value): bulb_logger.error( f'NotImplementedError("bulb doesn\'t provide a DB representation for AnonymousUser.")' ) raise NotImplementedError( "bulb doesn't provide a DB representation for AnonymousUser.")
def get(cls, uuid=None, session_key=None, order_by=None, limit=None, skip=None, desc=False, only=None, filter=None, return_query=False): """ This method allow the retrieving of Session (or of one of its children classes) instances. :param uuid: The Universal Unique Identifier of a session to get an unique session instance. :param session_key: The session_key of a session to get an unique session instance. :param order_by: Must be the name of the property with which the returned datas will be sorted. Examples : "datetime", "first_name", etc... :param limit: Must be an integer. This parameter defines the number of returned elements. :param skip: Must be an integer. This parameter defines the number of skipped elements. For example if self.skip = 3, the 3 first returned elements will be skipped. :param desc: Must be a boolean. If it is False the elements will be returned in an increasing order, but it is True, they will be returned in a descending order. :param only: Must be a list of field_names. If this parameter is filled, the return will not be Permission instances, but a dict with "only" the mentioned fields. :param filter: Must be Q statement. You must use the Q class stored in bulb.db Example: Q(name__contains="al") | Q(age__year__lte=8) :param return_query: Must be a boolean. If true, the method will return the cypher query. :return: If uuid is None, a list will be returned. Else it will be a unique instance. """ where_statement = "" property_statement = "" order_by_statement = "" limit_statement = "" skip_statement = "" desc_statement = "" # Build the property_statement. if uuid is not None and session_key is not None: property_statement = "{uuid:'%s', session_key:'%s'}" % (uuid, session_key) elif uuid is not None: property_statement = "{uuid:'%s'}" % uuid elif session_key is not None: property_statement = "{session_key:'%s'}" % session_key # Build the match_statement. cyher_labels = node_models.DatabaseNode.format_labels_to_cypher(cls._get_labels()) match_statement = f"MATCH (s:{cyher_labels} {property_statement})" # Build the where statement. if filter is not None: where_statement = "WHERE " + filter where_statement = where_statement.replace("n.", "s.") # Build the with_statement. with_statement = "WITH s" # Build order_by statements. if order_by is not None: order_by_statement = f"ORDER BY s.{order_by}" # Build return_statement statements. if not only: return_statement = "RETURN (s)" else: only_statement_list = [] for element in only: only_statement_list.append(f"s.{element}") only_statement = ", ".join(only_statement_list) return_statement = f"RETURN {only_statement}" # Build limit_statement. if limit is not None: if not isinstance(limit, str) and not isinstance(limit, int): bulb_logger.error( f'BULBSessionError("The \'limit\' parameter of the get() method of {cls.__name__} must be a string or an integer.")') raise BULBSessionError( f"The 'limit' parameter of the get() method of {cls.__name__} must be a string or an integer.") else: limit_statement = f"LIMIT {limit}" # Build skip_statement and add its required variable. if skip is not None: if not isinstance(skip, str) and not isinstance(skip, int): bulb_logger.error( f'BULBSessionError("The \'skip\' parameter of the get() method of {cls.__name__} must be a string or an integer.")') raise BULBSessionError( f"The 'skip' parameter of the get() method of {cls.__name__} must be a string or an integer.") else: skip_statement = f"SKIP {skip}" # Build desc_statement. if not isinstance(desc, bool): bulb_logger.error( f'BULBSessionError("The \'desc\' parameter of the get() method of {cls.__name__} must be a boolean.")') raise BULBSessionError( f"The 'desc' parameter of the get() method of {cls.__name__} must be a boolean.") else: if desc is True: desc_statement = "DESC" request_statement = """ %s %s %s %s %s %s %s %s """ % (match_statement, where_statement, with_statement, order_by_statement, desc_statement, skip_statement, limit_statement, return_statement) if return_query is False: response = gdbh.r_transaction(request_statement) if response: if only is None: fake_instances_list = [] for session_object in response: fake_instances_list.append(cls.build_fake_instance(session_object["s"], forced_fake_instance_class=cls)) if uuid is not None or session_key is not None: return fake_instances_list[0] else: return fake_instances_list else: return response else: return None else: return request_statement
def push_src_staticfiles(src_type, local_staticfiles_folder_path, pages_to_refresh_names=None): """ This method post new source staticfiles on the SFTP server. :param (required) src_type: The type of source staticfiles to post on the sftp. "src" / "bundled" :param (required) local_staticfiles_folder_path: The local staticfiles folder path. :return: """ if src_type == "raw": sftp_staticfiles_folder_path = "/www/staticfiles/raw_src" elif src_type == "bundled": sftp_staticfiles_folder_path = "/www/staticfiles/bundled_src" else: bulb_logger.error( f'BULBStaticfilesError("The \'src_type\' parameter of the clear_staticfiles() method should be \'raw\' or \'bundled\'. It is {str(src_type)}.")' ) raise BULBStaticfilesError( f"The 'src_type' parameter of the clear_staticfiles() method should be 'raw' or 'bundled'. It is {str(src_type)}." ) if pages_to_refresh_names is None: with SFTP.connect() as sftp: print("\n------------------------------------------" + ("---" if src_type == "raw" else "-------")) print( f"-- UPLOAD NEW {src_type.upper()} SRC STATICFILES ON SFTP --" ) print(("---" if src_type == "raw" else "-------") + "------------------------------------------\n") print( "\nThis operation could take few minutes (it depends of the number and the weight of your static files)...\n" ) try: sftp.put_r(local_staticfiles_folder_path, sftp_staticfiles_folder_path) # Check and create default storage folders if they are not already created. except FileNotFoundError: if not sftp.exists("/www/staticfiles"): sftp.mkdir("/www/staticfiles") if not sftp.exists(f"/www/staticfiles/{src_type}_src"): sftp.mkdir(f"/www/staticfiles/{src_type}_src") sftp.put_r(local_staticfiles_folder_path, sftp_staticfiles_folder_path) finally: print("Done ✔\n") else: with SFTP.connect() as sftp: for application, elements in pages_to_refresh_names.items(): print("\n------------------------------------------" + ("---" if src_type == "raw" else "-------")) print( f"-- UPLOAD NEW {application.upper()} {src_type.upper()} SRC STATICFILES ON SFTP --" ) print(("---" if src_type == "raw" else "-------") + "------------------------------------------\n") local_module_folder_path = local_staticfiles_folder_path + "/" + application sftp_module_folder_path = sftp_staticfiles_folder_path + "/" + application try: sftp.put_r(local_module_folder_path, sftp_module_folder_path) # Check and create default storage folders if they are not already created. except FileNotFoundError: if not sftp.exists("/www/staticfiles"): sftp.mkdir("/www/staticfiles") if not sftp.exists(f"/www/staticfiles/{src_type}_src"): sftp.mkdir(f"/www/staticfiles/{src_type}_src") if not sftp.exists( f"/www/staticfiles/{src_type}_src/{application}" ): sftp.mkdir( f"/www/staticfiles/{src_type}_src/{application}" ) sftp.put_r(local_module_folder_path, sftp_module_folder_path) finally: print("Done ✔\n")
def connect(log=None): use_sftp = settings.BULB_USE_SFTP if use_sftp is True: host = settings.BULB_SFTP_HOST if host is None: bulb_logger.error( 'BULBSftpError("To establish an SFTP connection you have to provide the a host server. Please put it in the BULB_SFTP_HOST variable in \'settings.py\'.")' ) raise BULBSftpError( "To establish an SFTP connection you have to provide the a host server. Please put it in the BULB_SFTP_HOST variable in \'settings.py\'." ) port = settings.BULB_SFTP_PORT if port is None: port = 22 username = settings.BULB_SFTP_USER if username is None: bulb_logger.error( 'BULBSftpError("To establish an SFTP connection you have to provide the a server user name. Please put it in the BULB_SFTP_USER variable in \'settings.py\'.")' ) raise BULBSftpError( "To establish an SFTP connection you have to provide the a server user name. Please put it in the BULB_SFTP_USER variable in \'settings.py\'." ) known_hosts = settings.BULB_SFTP_KNOWN_HOSTS password = settings.BULB_SFTP_PASSWORD private_key_path = settings.BULB_SFTP_PRIVATE_KEY_PATH private_key_pass = settings.BULB_SFTP_PRIVATE_KEY_PASS if known_hosts is None: if password is not None: keydata = settings.BULB_SFTP_HOST_SSH_KEY if keydata is None: raise BULBHostSSHKeyError( "To establish an SFTP connection you have to provide the SSH key of the server. Please put it in the BULB_SFTP_HOST_SSH_KEY variable in 'settings.py'." ) else: key = paramiko.RSAKey(data=decodebytes(keydata)) cnopts = None with warnings.catch_warnings(): warnings.simplefilter("ignore", category=UserWarning) cnopts = pysftp.CnOpts() cnopts.hostkeys.add(host, 'ssh-rsa', key) return pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts, log=log) if private_key_path is not None: if private_key_pass is not None: return pysftp.Connection( host=host, port=port, username=username, private_key=private_key_path, private_key_pass=private_key_pass, log=log) else: return pysftp.Connection(host=host, port=port, username=username, private_key=private_key_path, log=log) else: # To clean : # key = paramiko.rsakey.RSAKey(data=decodebytes(hostkey)) # # with warnings.catch_warnings(): # warnings.simplefilter("ignore", category=UserWarning) cnopts = pysftp.CnOpts() cnopts.hostkeys.load(known_hosts) # cnopts.hostkeys.add(host, 'ssh-rsa', key) # cnopts.hostkeys = None if password is not None: return pysftp.Connection(host=host, port=port, username=username, password=password, cnopts=cnopts, log=log) if private_key_path is not None: if private_key_pass is not None: return pysftp.Connection( host=host, port=port, username=username, private_key=private_key_path, private_key_pass=private_key_pass, cnopts=cnopts, log=log) else: return pysftp.Connection(host=host, port=port, username=username, private_key=private_key_path, cnopts=cnopts, log=log)
def handle(self, *args, **kwargs): # Get the staticfiles folder path raw_staticfiles_folder_path = get_folders_paths_list("staticfiles") if raw_staticfiles_folder_path is not None: bundled_staticfiles_folder_path = get_folders_paths_list( "bundled_staticfiles") pages_to_refresh_names = None if "pages-to-refresh-names" in kwargs: # Prevent errors if datas are corrupted. try: pages_to_refresh_names = json.loads( kwargs["pages-to-refresh-names"]) except: pass if kwargs["raw"]: SFTP.push_src_staticfiles( src_type="raw", local_staticfiles_folder_path=raw_staticfiles_folder_path, pages_to_refresh_names=pages_to_refresh_names) if kwargs["bundled"]: if bundled_staticfiles_folder_path is not None: SFTP.push_src_staticfiles( src_type="bundled", local_staticfiles_folder_path= bundled_staticfiles_folder_path, pages_to_refresh_names=pages_to_refresh_names) else: bulb_logger.error( 'BULBStaticfilesError("The bundled_staticfiles folder was not found. Please execute the \'collectstatic\' and \'bundlestatic\' commands before pushing it to your sftp server.")' ) raise BULBStaticfilesError( "The bundled_staticfiles folder was not found. Please execute the 'collectstatic' and 'bundlestatic' commands before pushing it to your sftp server." ) if not kwargs["raw"] and not kwargs["bundled"]: SFTP.push_src_staticfiles( src_type="raw", local_staticfiles_folder_path=raw_staticfiles_folder_path, pages_to_refresh_names=pages_to_refresh_names) if bundled_staticfiles_folder_path is not None: SFTP.push_src_staticfiles( src_type="bundled", local_staticfiles_folder_path= bundled_staticfiles_folder_path, pages_to_refresh_names=pages_to_refresh_names) else: bulb_logger.error( 'BULBStaticfilesError("The bundled_staticfiles folder was not found. Please execute the \'collectstatic\' and \'bundlestatic\' commands before pushing it to your sftp server.")' ) raise BULBStaticfilesError( "The bundled_staticfiles folder was not found. Please execute the 'collectstatic' and 'bundlestatic' commands before pushing it to your sftp server." ) else: bulb_logger.error( 'BULBStaticfilesError("The staticfiles folder was not found. Please execute the \'collectstatic\' command before pushing it to your sftp server.")' ) raise BULBStaticfilesError( "The staticfiles folder was not found. Please execute the 'collectstatic' command before pushing it to your sftp server." )
def clear_src_staticfiles(src_type=None, no_purge=False, pages_to_refresh_names=None): """ This method delete old source staticfiles on the SFTP server. :param (required) src_type: The type(s) of source staticfiles to remove. "src" / "bundled" :return: """ if src_type is not None: if src_type == "raw": sftp_staticfiles_folder_path = "/www/staticfiles/raw_src" elif src_type == "bundled": sftp_staticfiles_folder_path = "/www/staticfiles/bundled_src" else: bulb_logger.error( f'BULBStaticfilesError("The \'src_type\' parameter of the clear_staticfiles() method should be \'raw\', \'bundled\'. It is {str(src_type)}.")' ) raise BULBStaticfilesError( f"The 'src_type' parameter of the clear_staticfiles() method should be 'raw', 'bundled'. It is {str(src_type)}." ) # If there isn't a list of modified modules' names : remove all. if pages_to_refresh_names is None: with SFTP.connect() as sftp: files_to_purge_list = [] def remove_file(path): if sftp.isfile(path): rectified_path = "".join( [x for x in path][4:]) # Delete '/www' on the path files_to_purge_list.append(rectified_path) sftp.remove(path) print("'" + path + "'", " removed.") paths_list = [] def add_to_paths_list(x): paths_list.append(x) print( f"\n-----------------------------------------{'----' if src_type == 'bundled' else ''}" ) print( f"-- REMOVE OLD {src_type.upper()} SRC FILES FROM SFTP --" ) print( f"-----------------------------------------{'----' if src_type == 'bundled' else ''}\n" ) try: sftp.walktree(sftp_staticfiles_folder_path, fcallback=remove_file, dcallback=remove_file, ucallback=remove_file) except FileNotFoundError: print( f"\n There were no {src_type} source files to remove on the sftp.\n" ) print( f"\n-----------------------------------------------{'----' if src_type == 'bundled' else ''}" ) print( f"-- REMOVE OLD {src_type.upper()} SRC DIRECTORIES FROM SFTP --" ) print( f"-----------------------------------------------{'----' if src_type == 'bundled' else ''}\n" ) try: sftp.walktree(sftp_staticfiles_folder_path, fcallback=add_to_paths_list, dcallback=add_to_paths_list, ucallback=add_to_paths_list) except FileNotFoundError: print( f"\n There were no {src_type} source directories to remove on the sftp.\n" ) else: while paths_list: for path in paths_list: try: sftp.rmdir(path) pass except: continue else: print(path, " removed !") paths_list.remove(path) if no_purge is False: SFTP.purge_src_staticfiles( files_to_purge_list=files_to_purge_list) else: return files_to_purge_list # Else remove only modified modules. else: files_to_purge_list = [] with SFTP.connect() as sftp: print("TEST FOR LOOP") for application, elements in pages_to_refresh_names.items(): print("application") print(application) print("elements") print(elements) bundled_application_sftp_path = "/www/staticfiles/bundled_src/" + application raw_application_sftp_path = "/www/staticfiles/raw_src/" + application print("bundled_application_sftp_path") print(bundled_application_sftp_path) print("raw_application_sftp_path") print(raw_application_sftp_path) def remove_element_staticfiles(path): print("def remove_element_staticfiles") print("path") print(path) if sftp.isfile(path): print("path is file") for element in elements: print("element") print(element) print("element split -1") print(path.split("/")[-1]) if element in path.split("/")[-1]: print("ÇA PASSE !!!") print("element is in") rectified_path = "".join([ x for x in path ][4:]) # Delete '/www' on the path print("rectified_path") print(rectified_path) files_to_purge_list.append(rectified_path) sftp.remove(path) print("'" + path + "'", " removed.") print( f"\n----------------------------------------{'-' * len(application)}" ) print( f"-- REMOVE OLD '{application}' SRC FILES FROM SFTP --" ) print( f"----------------------------------------{'-' * len(application)}\n" ) try: # Remove bundled files. try: sftp.walktree(bundled_application_sftp_path, fcallback=remove_element_staticfiles, dcallback=remove_element_staticfiles, ucallback=remove_element_staticfiles) except FileNotFoundError: print( f"\n There were no bundled source files to remove on the sftp for the {application} module.\n" ) # Remove raw files. try: sftp.walktree(raw_application_sftp_path, fcallback=remove_element_staticfiles, dcallback=remove_element_staticfiles, ucallback=remove_element_staticfiles) except FileNotFoundError: print( f"\n There were no raw source files to remove on the sftp for the {application} module.\n" ) sftp.rmdir(bundled_application_sftp_path) sftp.rmdir(raw_application_sftp_path) except: pass if no_purge is False: SFTP.purge_src_staticfiles( files_to_purge_list=files_to_purge_list) else: return files_to_purge_list
def preserve_or_login(request, if_authentication_user=AnonymousUser()): from_authentication_user = AnonymousUser() from_request_user = AnonymousUser() try: if not isinstance(if_authentication_user, AnonymousUser): if isinstance(if_authentication_user, User): from_authentication_user = if_authentication_user if not isinstance(request.user, AnonymousUser): if isinstance(request.user, User): from_request_user = request.user if isinstance(if_authentication_user, AnonymousUser) and isinstance( request.user, AnonymousUser): #changed bulb_logger.error( 'BULBLoginError("To login an user with the \'preserve_or_login()\' function, you must provide as function\'s parameters : the request and the user object.")' ) raise BULBLoginError( "To login an user with the 'preserve_or_login()' function, you must provide as function's parameters : the request and the user object." ) except BULBLoginError: force_clear_user_session(request) bulb_logger.error( 'BULBLoginError("To login an user with the \'preserve_or_login()\' function, you must provide as function\'s parameters : the request and the user object.")' ) raise else: # If the function is called during an authentication, to login an user : if not isinstance(from_authentication_user, AnonymousUser): # Prevent double authentication : if "logged_user_uuid" in request.session: if request.session["logged_user_uuid"] is not None: #If the user is the same in database and session : if from_request_user.uuid == from_authentication_user.uuid == request.session[ 'logged_user_uuid']: current_user_session = from_authentication_user.session.get( )[0] # If the session is the same in database and in cookie : if current_user_session and request.session.session_key \ and current_user_session.session_key == request.session.session_key: # If settings.BULB_SESSION_CHANGE_ON_EVERY_REQUEST is True, delete and create a new session # Else, just preserve the current session. if settings.BULB_SESSION_CHANGE_ON_EVERY_REQUEST: force_clear_user_session( request, user=from_authentication_user) _login_user(request, from_authentication_user) else: force_clear_user_session(request, user=from_authentication_user) _login_user(request, from_authentication_user) else: force_clear_user_session(request, user=from_authentication_user) _login_user(request, from_authentication_user) else: force_clear_user_session(request, user=from_authentication_user) _login_user(request, from_authentication_user) # If the user is not provided during authentication (he is the currently logged user stored in request.user) elif not isinstance(from_request_user, AnonymousUser): # If a 'logged_user_uuid' is already in the session (if the user is MAYBE already logged) : if "logged_user_uuid" in request.session: if request.session['logged_user_uuid'] is not None: # If the user is the same in database and session : if from_request_user.uuid == request.session[ 'logged_user_uuid']: session_request = from_request_user.session.get() current_user_session = None if session_request is not None: current_user_session = session_request[0] # If the session is the same in database and in cookie : if current_user_session and request.session.session_key \ and current_user_session.session_key == request.session.session_key: # If settings.BULB_SESSION_CHANGE_ON_EVERY_REQUEST is True, delete and create a new session # Else, just preserve the current session. if settings.BULB_SESSION_CHANGE_ON_EVERY_REQUEST: force_clear_user_session(request) _login_user(request, from_request_user) # If the sessions datas are not identical else: force_clear_user_session(request) # If the users datas are not identical else: force_clear_user_session(request) # Else if the user is not already logged in : else: force_clear_user_session(request) else: force_clear_user_session(request)
def create_super_user(cls, **extrafields): bulb_logger.error( f'NotImplementedError("bulb doesn\'t provide a DB representation for AnonymousUser.")' ) raise NotImplementedError( "bulb doesn't provide a DB representation for AnonymousUser.")
def handle(self, *args, **options): if not settings.DEBUG: """ If the command is executed when DEBUG = False, errors can occur from the bulb templatetags. Indeed, if DEBUG = False, if {% static_raw_src %}, {% static_bundled_src %} are used, staticfiles will be recovered from the SFTP : this will cause that the 'collectstatic command will collect staticfiles from the old files on the SFTP, and not from the local new files. But also in certain cases, bundled staticfiles will be used : this will cause that the new bundle files will be build from the old bundle files. See : TODO : add the related documentation page url. """ bulb_logger.error( 'BULBStaticfilesError("The DEBUG variable must be set on \'True\' to handle new staticfiles.")' ) raise BULBStaticfilesError( "The DEBUG variable must be set on 'True' to handle new staticfiles." ) else: added_files_paths = None modified_files_paths = None removed_files_paths = None # Prevent errors if datas are corrupted. try: added_files_paths = json.loads(options["added"]) except: pass try: modified_files_paths = json.loads(options["modified"]) except: pass try: removed_files_paths = json.loads(options["removed"]) except: pass print("added_files_paths") print(added_files_paths) print("modified_files_paths") print(modified_files_paths) print("removed_files_paths") print(removed_files_paths) # Collect staticfiles. print("\n--------------------------") print("-- COLLECT STATIC FILES --") print("--------------------------\n") subprocess.call("python manage.py collectstatic --clear --noinput", shell=True) if not added_files_paths and not modified_files_paths and not removed_files_paths: # Remove old source staticfiles and collect them in a list to purge them on the CDN at the end. raw_files_to_purge_list = SFTP.clear_src_staticfiles( src_type="raw", no_purge=True) bundled_files_to_purge_list = SFTP.clear_src_staticfiles( src_type="bundled", no_purge=True) files_to_purge_list = raw_files_to_purge_list + bundled_files_to_purge_list if settings.BULB_SFTP_SRC_STATICFILES_MODE == "raw" or settings.BULB_SFTP_SRC_STATICFILES_MODE == "both": # Push new source staticfiles on the SFTP. subprocess.call("python manage.py pushstatic --raw", shell=True) if settings.BULB_SFTP_SRC_STATICFILES_MODE == "bundled" or settings.BULB_SFTP_SRC_STATICFILES_MODE == "both": # Generate the bundled_staticfiles folder which contains all the bundle of the project staticfiles. subprocess.call("python manage.py bundlestatic", shell=True) # Push new source staticfiles on the SFTP. subprocess.call("python manage.py pushstatic --bundled", shell=True) # Purge all old staticfiles. SFTP.purge_src_staticfiles( files_to_purge_list=files_to_purge_list) else: # 'amr' = added, modified or removed amr_files_paths = [] amr_files_paths += added_files_paths if added_files_paths is not None else [] amr_files_paths += modified_files_paths if modified_files_paths is not None else [] amr_files_paths += removed_files_paths if removed_files_paths is not None else [] print("amr_files_paths") print(amr_files_paths) # Remove doublons. amr_files_paths = list(set(amr_files_paths)) print("amr_files_paths 2") print(amr_files_paths) # Collect all elements(pages, module, etc.) with their associated staticifiles. pages = {} # Get paths of all "pages" folders of the project. pages_folders_paths = get_folders_paths_list("pages") # Loop on each "pages" folders of the project. for pages_folder_path in pages_folders_paths: splitted_pages_folder_path = pages_folder_path.split("/") # Get the parent folder name and build its future path in the bundled_staticfiles folder. application_name = splitted_pages_folder_path[ -2] if splitted_pages_folder_path[ -2] != "templates" else splitted_pages_folder_path[ -3] if not application_name in pages.keys(): pages[application_name] = {} # Retrieve all pages with their associated staticfiles' paths. for root, dirs, files in os.walk(pages_folder_path): for file in files: if not file in pages[application_name].keys(): pages[application_name][file] = [] file_path = pages_folder_path + "/" + file template_content = None with open(file_path, "r") as template_file: template_content = template_file.read() template_content = template_content.replace( '{% url', 'xxx') template_object = Template(template_content) context = Context({ "DEBUG": True, "BULB_REQUIRES_INITIAL_PATHS": True }) template = template_object.render(context) doc = lxml.html.document_fromstring(template) links = doc.xpath("//link[@rel='stylesheet']") # Add CSS dependencies to the entry.js file. for link in links: href_value = link.get("href") # Ignore href with external urls. if href_value[:4] == "http": continue else: related_staticfile_path = href_value.split( "/")[-1] pages[application_name][file].append( related_staticfile_path) # Add JS dependencies to the entry.js file. scripts = doc.xpath("//script") for script in scripts: src_value = script.get("src") # Ignore href with external urls. if src_value is None: continue elif src_value[:4] == "http": continue else: related_staticfile_path = href_value.split( "/")[-1] pages[application_name][file].append( related_staticfile_path) # # Prevent wrong staticfiles' paths format. # for path in amr_files_paths: # # # Ignore all files that are not staticfiles. # if path[-3:] == ".js" or path[-4:] == ".css" or path[-5:] == ".sass" or path[-5:] == ".scss": # # # Uniformize path's format. # if path[0] == "/": # path = path[1:] # # splitted_path = path.split("/") # # # Find application and element (page, element, module, etc.) names. # application_name = None # element_name = None # # if splitted_path[0] != "www" or splitted_path[1] != "staticfiles": # if splitted_path[1] == splitted_path[3]: # application_name = splitted_path[1] # element_name = splitted_path[6].split(".")[0] # # else: # application_name = splitted_path[4] # element_name = splitted_path[5].split(".")[0] # # if application_name is not None and element_name is not None: # # if not application_name in pages_to_refresh.keys(): # pages_to_refresh[application_name] = [] # # if not element_name in pages_to_refresh[application_name]: # pages_to_refresh[application_name].append(element_name) # # # print("pages_to_refresh (APRÈS FORMATTAGE)") # print(pages_to_refresh) # Retrieve the list of pages to resfresh in two different formats (for the bundle an clear commands). pages_to_refresh_paths = [] pages_to_refresh_names = {} # Prevent wrong staticfiles' paths format. for path in amr_files_paths: # Ignore all files that are not staticfiles. if path[-3:] == ".js" or path[-4:] == ".css" or path[ -5:] == ".sass" or path[-5:] == ".scss": # Uniformize path's format. if path[0] == "/": path = path[1:] splitted_path = path.split("/") # Find application and element (page, element, module, etc.) names. application_name = None element_name = None if splitted_path[0] != "www" or splitted_path[ 1] != "staticfiles": if splitted_path[1] == splitted_path[3]: application_name = splitted_path[1] element_name = splitted_path[-1] else: application_name = splitted_path[4] element_name = splitted_path[-1] if application_name is not None and element_name is not None: for page_path, staticfiles_names in pages[ application_name].items(): for staticfiles_name in staticfiles_names: if staticfiles_name == element_name: if not path in pages_to_refresh_path: pages_to_refresh_paths.append(path) if not element_name in pages_to_refresh_names: if not application_name in pages_to_refresh_names.keys( ): pages_to_refresh_names[ application_name] = [] pages_to_refresh_names[ application_name].append( element_name.split(".")[0]) print("pages") print(pages) print("pages_to_refresh_names") print(pages_to_refresh_names) print("pages_to_refresh_paths") print(pages_to_refresh_paths) # Remove old source staticfiles and collect them in a list to purge them on the CDN at the end. files_to_purge_list = SFTP.clear_src_staticfiles( no_purge=True, pages_to_refresh_names=pages_to_refresh_names) if settings.BULB_SFTP_SRC_STATICFILES_MODE == "raw" or settings.BULB_SFTP_SRC_STATICFILES_MODE == "both": # Push new source staticfiles on the SFTP. subprocess.call( f"python manage.py pushstatic --raw --pages-to-refresh-names {json.dumps(pages_to_refresh_names)}", shell=True) if settings.BULB_SFTP_SRC_STATICFILES_MODE == "bundled" or settings.BULB_SFTP_SRC_STATICFILES_MODE == "both": # Generate the bundled_staticfiles folder which contains all the bundle of the project staticfiles. subprocess.call( "python manage.py bundlestatic --pages-to-refresh-paths {json.dumps(pages_to_refresh_paths)}", shell=True) # Push new source staticfiles on the SFTP. subprocess.call( "python manage.py pushstatic --bundled --pages-to-refresh-names {json.dumps(pages_to_refresh_names)}", shell=True) # Purge all old staticfiles. if files_to_purge_list: SFTP.purge_src_staticfiles( files_to_purge_list=files_to_purge_list)
def get_session_store_class(cls): bulb_logger.error('NotImplementedError') raise NotImplementedError
def handle(self, *args, **options): if not settings.DEBUG: """ If the command is executed when DEBUG = False, errors can occur from the bulb templatetags. Indeed, if DEBUG = False, if {% static_raw_src %}, {% static_bundled_src %} are used, staticfiles will be recovered from the SFTP : this will cause that the 'collectstatic command will collect staticfiles from the old files on the SFTP, and not from the local new files. But also in certain cases, bundled staticfiles will be used : this will cause that the new bundle files will be build from the old bundle files. See : TODO : add the related documentation page url. """ bulb_logger.error( 'BULBStaticfilesError("The DEBUG variable must be set on \'True\' to handle new staticfiles.")') raise BULBStaticfilesError("The DEBUG variable must be set on 'True' to handle new staticfiles.") else: # Bundling temporary files paths : package_file_path = None package_lock_file_path = None babelrc_file_path = None entry_file_path = None webpack_config_file_path = None # Test if the staticfiles folder exist. if not os.path.isdir(os.path.join(BASE_DIR, "staticfiles")): bulb_logger.error( 'BULBStaticfilesError("The \'staticfiles\' folder was not found. Please run the \'python manage.py collectstatic\' command.")') raise BULBStaticfilesError( "The 'staticfiles' folder was not found. Please run the 'python manage.py collectstatic' command.") else: # Prevent errors if datas are corrupted. try: bulb_path = bulb.__path__[0] # Create the package.json file. package_file_path = os.path.join(BASE_DIR, "package.json") package_lock_file_path = os.path.join(BASE_DIR, "package-lock.json") package_file = open(package_file_path, "w") package_file.write(open(bulb_path + "/sftp_and_cdn/webpack_files/package.json", "r").read()) package_file.close() # Create the .babelrc file. babelrc_file_path = os.path.join(BASE_DIR, ".babelrc") babelrc_file = open(babelrc_file_path, "w") babelrc_file.write(open(bulb_path + "/sftp_and_cdn/webpack_files/.babelrc", "r").read()) babelrc_file.close() # Create the babel.config.js file. # babel_config_file_path = os.path.join(BASE_DIR, "babel.config.js") # babel_config_file = open(babel_config_file_path, "w") # babel_config_file.write(open(bulb_path + "/sftp_and_cdn/webpack_files/babel.config.js", "r").read()) # babel_config_file.close() # Install npm dependencies subprocess.call(f"npm install", shell=True) # Get paths of all "pages" folders of the project. pages_folders_paths = get_folders_paths_list("pages") print("pages_folders_paths") print(pages_folders_paths) # Get pages to refresh. pages_to_refresh_names = None if "pages-to-refresh-names" in options: try: pages_to_refresh_names = json.loads(options["pages-to-refresh-names"]) except: pass print("pages_to_refresh_names") print(pages_to_refresh_names) # Get the bundled_staticfiles folder path. bundled_staticfiles_folder_path = os.path.join(BASE_DIR, "bundled_staticfiles") # Remove the old bundled_staticfiles folder and create a new one. subprocess.call(f"rm -rf {bundled_staticfiles_folder_path}", shell=True) os.mkdir(bundled_staticfiles_folder_path) print("\n--------------") print("-- BUNDLING --") print("--------------\n") # Loop on each "pages" folders of the project. for pages_folder_path in pages_folders_paths: splitted_pages_folder_path = pages_folder_path.split("/") # Get the parent folder name and build its future path in the bundled_staticfiles folder. parent_folder_name = splitted_pages_folder_path[-2] if splitted_pages_folder_path[-2] != "templates" else splitted_pages_folder_path[-3] parent_folder_path = bundled_staticfiles_folder_path + "/" + parent_folder_name print("\n " + ("-" * (len(parent_folder_name) + 6))) print(" -- " + parent_folder_name.upper() + " --") print(" " + ("-" * (len(parent_folder_name) + 6)) + "\n") # Create the current parent folder in the bundled_staticifiles folder. os.mkdir(parent_folder_path) print("mkdir ok !") # Loop on each page of the current "pages" folder, get their dependencies and bundle them. def bundle_file_staticfiles(file): print("bfs is executed") file_path = pages_folder_path + "/" + file print("\n -", file) template_content = None with open(file_path, "r") as template_file: template_content = template_file.read() template_content = template_content.replace('{% url', 'xxx') template_object = Template(template_content) context = Context({"DEBUG": True}) template = template_object.render(context) doc = lxml.html.document_fromstring(template) # Create the entry.js file. entry_file_path = os.path.join(BASE_DIR, "entry.js") entry_file = open(entry_file_path, "a") # Add polyfill dependencies to the entry.js file. if settings.BULB_SRC_BUNDLES_USE_WEBPACK_POLYFILL: entry_file.write("import 'core-js';import 'regenerator-runtime/runtime';") print("\n Searching CSS dependencies...") print(" Found :\n") links = doc.xpath("//link[@rel='stylesheet']") # Add CSS dependencies to the entry.js file. for link in links: href_value = link.get("href") print(" -", href_value) # Ignore href with external urls. if href_value[:4] == "http": continue else: related_staticfiles_path = "." + "/staticfiles" + href_value[7:] entry_file.write(f"import {'a' + uuid.uuid4().hex} from '{related_staticfiles_path}';") # Add JS dependencies to the entry.js file. print("\n Searching JS dependencies...") print(" Found :\n") scripts = doc.xpath("//script") for script in scripts: src_value = script.get("src") print(" -", src_value) # Ignore href with external urls. if src_value is None: continue elif src_value[:4] == "http": continue else: related_staticfiles_path = "." + "/staticfiles" + src_value[7:] entry_file.write(f"import {'a' + uuid.uuid4().hex} from '{related_staticfiles_path}';") entry_file.close() print("\n ------------------------") print(" -- INITIALIZE WEBPACK --") print(" ------------------------\n") # Create webpack.config.js file. webpack_config_file_path = os.path.join(BASE_DIR, "webpack.config.js") webpack_config_file = open(webpack_config_file_path, "a") bundle_name = file[:-5] # Add file version. bulb_bundled_files_version = settings.BULB_BUNDLED_FILES_VERSION if bulb_bundled_files_version is not None: bundle_name = bundle_name + "&V=" + str(bulb_bundled_files_version) webpack_config_file.write(f"""// Don't modify this file, it is generated by a bulb's script (see sftp_and_cdn.management.commands.handlestatic.py) process.env.WEBPACK_ENTRY = ['{entry_file_path}']; process.env.WEBPACK_OUTPUT = '{parent_folder_path}'; process.env.BUNDLE_NAME = '{bundle_name}'; """) webpack_config_file.write(open(bulb_path + "/sftp_and_cdn/webpack_files/webpack.config.js", "r").read()) webpack_config_file.close() print(" Done ✔ ") print("\n ---------------------") print(" -- RUN WEBPACK --") print(" ---------------------\n") subprocess.call(f"npm run build", shell=True) # Remove the entry.js file. os.remove(entry_file_path) # # Remove the webpack.config.js file. os.remove(webpack_config_file_path) for root, dirs, files in os.walk(pages_folder_path): for file in files: if not pages_to_refresh_names: bundle_file_staticfiles(file) else: for page in pages_to_refresh_names: if file == page: bundle_file_staticfiles(file) break # Remove the .babelrc file os.remove(babelrc_file_path) # # Remove the package.json and package-lock.json files. os.remove(package_file_path) os.remove(package_lock_file_path) return bundled_staticfiles_folder_path # If any error occurs during bundling, all the temporary files are removed. except: # Remove the entry.js file. try: os.remove(entry_file_path) except (FileNotFoundError, TypeError): pass # # Remove the webpack.config.js file. try: os.remove(webpack_config_file_path) except (FileNotFoundError, TypeError): pass # Remove the .babelrc file. try: os.remove(babelrc_file_path) except (FileNotFoundError, TypeError): pass # # Remove the package.json and package-lock.json files. try: os.remove(package_file_path) except FileNotFoundError: pass try: os.remove(package_lock_file_path) except (FileNotFoundError, TypeError): pass
def process_response(self, request, response): """ If request.session was modified, or if the configuration is to save the session every time, save the changes and set a session cookie or delete the session cookie if the session has been emptied. """ try: accessed = request.session.accessed modified = request.session.modified empty = request.session.is_empty() except AttributeError: pass else: # First check if we need to delete this cookie. # The session should be deleted only if the session is entirely empty if settings.SESSION_COOKIE_NAME in request.COOKIES and empty: response.delete_cookie( settings.SESSION_COOKIE_NAME, path=settings.SESSION_COOKIE_PATH, domain=settings.SESSION_COOKIE_DOMAIN, ) else: if accessed: patch_vary_headers(response, ('Cookie', )) if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty: if request.session.get_expire_at_browser_close(): max_age = None expires = None else: max_age = request.session.get_expiry_age() expires_time = time.time() + max_age expires = http_date(expires_time) # Save the session data and refresh the client cookie. # Skip session save for 500 responses, refs #3881. if response.status_code != 500: try: request.session.save() except UpdateError: bulb_logger.error( 'SuspiciousOperation("The request\'s session was deleted before the request completed. The user may have logged out in a concurrent request, for example.")' ) raise SuspiciousOperation( "The request's session was deleted before the request completed. The user may have logged out in a concurrent request, for example." ) response.set_cookie( settings.SESSION_COOKIE_NAME, request.session.session_key, max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, path=settings.SESSION_COOKIE_PATH, secure=settings.SESSION_COOKIE_SECURE or None, httponly=settings.SESSION_COOKIE_HTTPONLY or None, samesite=settings.SESSION_COOKIE_SAMESITE, ) return response