From 2209fbeb54deb1e75febd31f3ad861f0db1d699f Mon Sep 17 00:00:00 2001 From: thomasabishop Date: Fri, 17 Jan 2025 13:56:50 +0000 Subject: [PATCH] feat: add tag export functionality --- db/eolas.db | Bin 1572864 -> 1572864 bytes src/cli.py | 9 ++++++--- src/controllers/controller.py | 9 +++++++-- src/services/graph_service.py | 18 +++++++++++------- src/services/tag_service.py | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/services/tag_service.py diff --git a/db/eolas.db b/db/eolas.db index 2b33bbfdf30cc2f349b759563d012907217a7560..157d5299d36a7a86579eb8a655f628d96784674a 100644 GIT binary patch delta 3705 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 delta 3563 zcmYL~X_OSz9mVTaSM@Tz)T37rhN)o$*{5LuS)~C{M;L7p1aWInHWz4F1trt71iAACeCfXQt}pBry$1jEM=h#x)vkjR~4a(k3nuCQRT#~n=9G2Treofv2UMp_~|01`6Rk;C&{%a zpO9C9FUc%;jl3M~n`9TtzwMSQ@Dr1lg4fGSz~9K_;0C!2{Iy()p|{8k%3I`Ol=E^C z%H!lh@KEK0j3b;m22G`3;;5vC8*d-@`H^}aD z@pHW#2d;FYokTrHcyYvgD!Cr5#o$|QJ+jDZ)+D7aX1@B$eD7s(K~KsJH%r5~Ip zec)`VgY8lUXGjK4mDnMhF1o>K;voG@5wL(w7I%WJ0!FYFu@4+0U;#TvkOiYe9vm%p zfGKe+m=v&sjTEqh#RZIDF|i3uh>hR~u>s`b1~4jM2Q$PqpkKfUri#_r#d~6vg7x1O z@I!fDTn7F_tOP$5WXInG+3{C#5%`IK5z3ol3HWD`0Y4IC!Jote@IwJ3lvl-EuqI%H z^0Jr(ZW1%WcSIUIE?|W62LTI|x5Y&8Ede7;I5x|j=B^FYpTxi9? zi!7u{S#BBNGAjfwwU8$zV+FtqEaXX9WO>1bR<{Q~3oOJ+nQsBgTo|d$IS9u%a{LDHEOaWUwz$ebJYs1ZjAL`Vja| z`P}J=-FazNv*R$xPhlV()RMHuhb>%;A?mSK#$dSBqQ;S`yUVop14 z*cHYd^XyQ@Ojoa{!$z-G#ZWEl#Y*R44ljLJXTvS7mJbaX8g`%V)l4t%)v_uErd7s! z^}K5K>KWAaqKY-DDy`qA4jDH0awp3$*+{3RPVQvqyHh54UZ3FPJTxThIc>0cPTq4~ z8(Zv7?D4!6vim&TDWkVnt9eXUt9VrIJ*EWSQ;zj~ka66$s%K1~>EW?f(7T{REo~|p zCyi8T;k`b8sr^JGsCspG&)c3As`IYr5OYud(KAvV)U{JBY>8uPS_a$Fpio|;1|rr#bVGSF2Dx*Ql4NUemEgRp-xmxn1{jry3v=Dk0K4pTdAbh;&Xvb?EFJZeh2% zTG@+_iqNmmNBgXzI)D;%@c|}*`_Pg7pD%azYMBrk)6|pmk#=5eG#%nj(brhdPwQ3a zn>zK>ecUPdK5b%$+>;ObQaS|j+vlPGj>q|8r{aE0K(o z0dmc<(%}Q1$?l1b{^l?OV=VNk>_&I#7UOxpUB&RM4)>YO{rnj}Kb(bHHOzga9>lzT z{;v%-)6OP21*->VH-=iAe3H(ak6{Pd0FKWw!F6^X#jKxt>TwdwOdx5MM(B%yA>+9k zb=44Y_Ow$E=owefG|_p}O=!Fl+Y(xm^vy;NadM ztGN4K3O=AY^&l4giNiw;!GnBIgUU`OjMksooV<^4hvUMq7aS9DhvF(wqsvnay&Pc8 z?rV>S(q3dE^hSVfbKm(O9+d%?oChKRE0YbG)-V)bA}SZCJtMZci$_(~oNzI?}}Ux=)@8ZPQ)7j9Z3-hAG`)+E6h9 z6vD_smG)i^lP2}ZX=5OwWstiFEg$(P%szHM>57b2kr!lLWtvlsw)<3Nojc>r=%B{7 zxF_C;j?$c5W7Y!AT8@}FYhwaP?^GicuNuxqHhwm!8E0RL&!N77;ngIN_hY@R(Rfc{ z^EH*tb(ee|dp^j%X_ukC*^r}*FYR=U+eHJW7%<<^@iL{8c&<$3uZAYG5f9FxWZkZ$ zxSb2Y4s_-@!kHjd%N)BZa8jXepkCvMRT}pZcF+UKN5HtCV~+6DSaa#<8%-liW+3Ve zz8am@qT^o?8;2VZ#Wie$MA2cxbMB_5(nH6iquthQ^h1MH1xl)!LV7WN%3w?E zLYzC91Z}8{n+9W9C+tjM!7?SiLN8$?&KRL788xEBtG`B74F}^N<{rmE=6ioQ{=86_8hQt zNnFF&W=&PTV?;Xc#HKObm(n<4jVXzXij IxPUSL1-?eBdjJ3c diff --git a/src/cli.py b/src/cli.py index d7951f7..8f99429 100644 --- a/src/cli.py +++ b/src/cli.py @@ -6,14 +6,17 @@ from services.database_service import DatabaseService from services.graph_service import GraphService from services.parse_file_service import ParseFileService from services.table_service import TableService +from services.tag_service import TagService database_service = DatabaseService("eolas") database_connection = database_service.connect() table_service = TableService(database_connection) parse_file_service = ParseFileService(EOLAS_DIRECTORY) graph_service = GraphService(database_connection) +tag_service = TagService(database_connection) + controller = Controller( - database_service, table_service, parse_file_service, graph_service + database_service, table_service, parse_file_service, graph_service, tag_service ) @@ -34,8 +37,8 @@ def main(): if args.command == "generate-graph": controller.execute("graph") - # if args.command == "export-tags": - # controller.export_tags() + if args.command == "export-tags": + controller.execute("tags") if __name__ == "__main__": diff --git a/src/controllers/controller.py b/src/controllers/controller.py index c33b22e..7083ddb 100644 --- a/src/controllers/controller.py +++ b/src/controllers/controller.py @@ -8,13 +8,13 @@ class Controller: table_service, parse_file_service, graph_service, - # tag_service, + tag_service, ): self.database_service = database_service self.table_service = table_service self.parse_file_service = parse_file_service self.graph_service = graph_service - # self.tag_service = tag_service + self.tag_service = tag_service def execute(self, operation): try: @@ -23,6 +23,8 @@ class Controller: return self.__populate_database() case "graph": return self.__generate_graph() + case "tags": + return self.__export_tags() except Exception as e: raise Exception(colored(f"ERROR {e}", "red")) finally: @@ -35,3 +37,6 @@ class Controller: def __generate_graph(self): self.graph_service.generate_graph() + + def __export_tags(self): + self.tag_service.export_tags() diff --git a/src/services/graph_service.py b/src/services/graph_service.py index a20dad1..ca84eb6 100644 --- a/src/services/graph_service.py +++ b/src/services/graph_service.py @@ -1,8 +1,10 @@ import json -from constants import GRAPH_OUTPUT_DIRECTORY -from services.sqlite_service import SqliteService -from models.graph_node import IGraphNode + +from constants import GRAPH_OUTPUT_DIRECTORY from models.graph_edge import IGraphEdge +from models.graph_node import IGraphNode +from services.sqlite_service import SqliteService + class GraphService(SqliteService): error_message_stub = "Could not retrieve contents of table:" @@ -20,7 +22,7 @@ class GraphService(SqliteService): "SELECT title FROM entries", error_message=f"{self.error_message_stub} entries", ) - + entries = [IGraphNode(id=entry[0], type="entry") for entry in entries] return tags + entries @@ -29,16 +31,18 @@ class GraphService(SqliteService): "SELECT * FROM entries_tags", error_message=f"{self.error_message_stub} entries_tags", ) - + tags = [IGraphEdge(source=f"#{tag[1]}", target=tag[0]) for tag in tags] backlinks = self._query( "SELECT * FROM backlinks", error_message=f"{self.error_message_stub} backlinks", ) - - backlinks = [IGraphEdge(source=f"{backlink[0]}", target = backlink[1]) for backlink in backlinks] + backlinks = [ + IGraphEdge(source=f"{backlink[0]}", target=backlink[1]) + for backlink in backlinks + ] return tags + backlinks diff --git a/src/services/tag_service.py b/src/services/tag_service.py new file mode 100644 index 0000000..d9193d4 --- /dev/null +++ b/src/services/tag_service.py @@ -0,0 +1,18 @@ +from services.sqlite_service import SqliteService + + +class TagService(SqliteService): + def __init__(self, db_connection): + super().__init__(db_connection) + + def __retrieve_entries_for_tag(self, tag): + entries = self._query("SELECT * FROM entries_tags WHERE tag_name = ?", (tag,)) + return sorted([entry[0] for entry in entries]) + + def export_tags(self): + tags = self._query("SELECT * FROM tags") + tags = sorted([tag[0] for tag in tags]) + tag_dict = {} + for tag in tags: + tag_dict[tag] = self.__retrieve_entries_for_tag(tag) + return tag_dict