123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- import os
- import datetime
- import json
- from studio import checklist
- from studio import story
- from studio import schedule
- from settings import settings
- from settings import talk
- def iftime(string):
-
- if len(string) != len("00:00:00"):
- return False
-
- if len(string.split(":")) != 3:
- return False
-
- try:
- for n, i in enumerate(string.split(":")):
-
- if len(i) != 2:
- return False
-
- i = int(i)
-
- if n == 0 and i > 23:
- return False
- if i > 59:
- return False
- except:
- pass
-
-
- return True
- def ifdate(string):
-
- if len(string) != len("1997/07/30"):
- return False
-
- new_date_format = "%Y/%m/%d"
- try:
- datetime.datetime.strptime(string, new_date_format)
- ret = True
- except:
- ret = False
-
- return ret
- def if_days_a_week(string):
-
- try:
- string = int(string)
- if string <= 7 and string >= 1:
- return True
- else:
- return False
- except Exception as e:
- print("fail", e)
- return False
-
- def get_legacy(project_location):
-
- # This function will return analytics data about a project. This particular
- # function is desinged to read old, Blender-Organizer projects. It's a first
- # step of conversion. And used to display basic analitycs into the
- # project-manager.
-
- name_tmp = project_location[project_location.rfind("/")+1:]
-
- data = {
- "name" : name_tmp, # Name of the project (typed properly)
- "director" : "", # Name of the project's director.
- "status" : "", # Projects's comment / type
- "donework" : 0.0, # Percentage of Assets and Scenes done
- "fraction" : 0.0, # Project's completion percentage
- "checklist" : 0.0, # Project's main checklist percentage
- "startdate" : "0000/00/00", # Date of the start of the project
- "deadline" : "0000/00/00", # Date when project's deadline is
- "duration" : 0, # Amount in days between startdate and deadline
- "timepassed" : 0.0, # Percentage of how much time had passed
- "dayspassed" : 0, # Amount of days since the startdate
- "needed" : 0, # Needed % per day
- "star" : 0, # If star is reached
- "chr_factor" : 1, # Importance factor for Characters
- "veh_factor" : 1, # Importance factor for Vehicles
- "loc_factor" : 1, # Importance factor for Locations
- "obj_factor" : 1, # Importance factor for Objects (Other)
- "rnd_factor" : 4, # Importance factor for Scenes (Renders)
- "chr" : 0.0, # Percentage of Characters done
- "veh" : 0.0, # Percentage of Vehicles done
- "loc" : 0.0, # Percentage of Locations done
- "obj" : 0.0, # Percentage of Objects (Other) done
- "rnd" : 0.0, # Percentage of Scenes (Renders) done
- "dates" : {} # Per date, detailed data about the project
- }
-
- # For the future we will have to use some kind of network system. Where
- # different people contribute to one project. For example director, writer,
- # animator. For this I want to introduce a USERNAME thing. I will add them
- # later to tasks and schedulings.
-
- Username = settings.read("Username")
- if not Username:
- Username = "Blender-Organizer User"
-
- # Okay let's get the name, director and status from the old file. Funny that
- # it still survived from so far back. In the Organizer 1.0 you had to manually
- # type in the number of assets that had to be done in each category.
-
- # And so for this task was created a file called "project.data". Here is
- # an example :
-
- # Project :Moria's Race
- # Status :Short Action Driving Film
- # Director :J.Y.Amihud
- # Character:1
- # Locations:1
- # Objects :1
- # Vehicles :1
- # Scenes :4
-
- # So that's survived up to the last Blender-Organizer. But no longer the
- # last 5 lines were utilized. I was using it mainly for the first 3 things.
-
- # Tho from a version 4.85 of Blender-Organizer those last lines were used
- # to controll the influence factor. Basically the number stored will multiply
- # the number of times a given category is counted in the final percentage.
-
- # For example animating scenes should take more then half the time of the
- # project. More then 50% of the project then should be in the scenes. But
- # previous / primitive algorythm was giving each category an even 20%. So
- # of course I fixed it. LOL.
- # I think for VCStudio I gonna make a more unified file format. That will
- # unite all "project.data", "percentage_hystory.data", "history.data" and
- # "schedule.data".
-
- # I'm going to still have the main checklist separate tho. The checklist
- # format is quite good.
-
- projectdata = open(project_location+"/project.data")
- projectdata = projectdata.read()
- projectdata = projectdata.split("\n")
-
- for line in projectdata:
-
- if line.startswith("Project"):
- data["name"] = line[line.find(":")+1:]
-
- elif line.startswith("Status"):
- data["status"] = line[line.find(":")+1:]
-
- elif line.startswith("Director"):
- data["director"] = line[line.find(":")+1:]
-
- # Next up some integer conversions. So...
-
- elif line.startswith("Character"):
- try:
- data["chr_factor"] = int(line[line.find(":")+1:])
- except:
- data["chr_factor"] = 1
-
-
- elif line.startswith("Vehicles"):
- try:
- data["veh_factor"] = int(line[line.find(":")+1:])
- except:
- data["veh_factor"] = 1
-
- elif line.startswith("Locations"):
- try:
- data["loc_factor"] = int(line[line.find(":")+1:])
- except:
- data["loc_factor"] = 1
-
- elif line.startswith("Objects"):
- try:
- data["obj_factor"] = int(line[line.find(":")+1:])
- except:
- data["obj_factor"] = 1
-
- elif line.startswith("Scenes"):
- try:
- data["rnd_factor"] = int(line[line.find(":")+1:])
- except:
- data["rnd_factor"] = 1
-
- # Okay this first file was easy. Let's now parse the main checklist and
- # get 5 more values. Funny thing is that for the old checklists and new
- # checklists you can use the same function to read them. ( The main check-
- # list data ). But old checklists had something else in there that was
- # making them a bit different from VCStudio checklists. It's the STR and FIN
- # variables in the beginig.
-
- # See in the Organizer 1.0 there was no scheduling system as there was in
- # Blender-Orgaznier 4.9. The scheduling was done per asset and not per
- # action in the checklist. So STR and FIN were 2 dates between which you
- # should have had working on the asset.
-
- # But in the main checklists ("project.progress") those 2 survived to the
- # late Blender-Organizer as a project startdate and deadline.
-
- # One more rub that I have is that date format was 00/00/0000 and not the
- # way better one 0000/00/00 which makes sorting easy. So yeah...
-
- old_date_format = "%d/%m/%Y"
- new_date_format = "%Y/%m/%d"
-
- projectdata = open(project_location+"/project.progress")
- projectdata = projectdata.read()
- projectdata = projectdata.split("\n")
-
- startdate = datetime.datetime.today()
- deadline = datetime.datetime.today()
-
- try:
- for line in projectdata:
- if line.startswith("STR"):
- startdate = datetime.datetime.strptime(line[4:], old_date_format)
- data["startdate"] = datetime.datetime.strftime(startdate, new_date_format)
-
- elif line.startswith("FIN"):
- deadline = datetime.datetime.strptime(line[4:], old_date_format)
- data["deadline"] = datetime.datetime.strftime(deadline, new_date_format)
- except:
-
- data["startdate"] = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
- data["deadline"] = datetime.datetime.strftime(datetime.datetime.today()+datetime.timedelta(days=30), new_date_format)
-
- # So we've go the dates. Let's calculate time perventage I guess.
- delta = deadline - startdate
- data["duration"] = int(delta.days)
-
- delta = datetime.datetime.today() - startdate
- data["dayspassed"] = int(delta.days)
-
- data["timepassed"] = data["dayspassed"] / data["duration"]
- if data["timepassed"] > 1.0:
- data["timepassed"] = 1.0
-
- # Now let's lauch the main checklist and get the data from there. I mean
- # the percentage. Btw It's just a hard thing. That I needed a separate
- # function for it.
-
- try:
- projectdata = checklist.get_list(project_location+"/project.progress")
- data["checklist"] = projectdata["fraction"]
- except:
- pass
-
- # NEXT THING. As I love to type it into place where people read me while I'm
- # working. We've got data from 2 files. Now we need to get data from ALL the
- # project.
-
- # First we going to get data about the assets. Because it's relativelly easy
- # compared to the story. For which you need to parce a crazy complicated .bos
- # file. Which is a complex database in it's own right.
-
- # So let's go and quickly get data about the assets.
-
- asstfols = ["chr", "veh", "loc", "obj"]
- astlist = []
-
- for n , f in enumerate(asstfols):
-
- flist = []
-
- if len(os.listdir(project_location+"/dev/"+f)) > 0:
- for asset in os.listdir(project_location+"/dev/"+f):
-
- if asset+".blend" in os.listdir(project_location+"/ast/"+f):
- flist.append(1.0)
-
- else:
- try:
- fcheck = checklist.get_list(project_location+"/dev/"+f+"/"+asset+"/asset.progress")
- flist.append(fcheck["fraction"])
- except:
- flist.append(0.0)
-
- # The multiplication thing that I was talking about earlier.
-
- multiply = data[f+"_factor"]
- for m in range(multiply):
- astlist.append(sum(flist)/len(flist))
-
- data[f] = sum(flist)/len(flist)
-
-
- # For the next step I need to have the story parsed and read. But it's going
- # to be so hard. That I will need to write a separate function for it.
-
- data["rnd"] = story.get_legacy(project_location)["fraction"]
-
- # After all of it we need to get the final project percentage.
- multiply = data["rnd_factor"]
- for m in range(multiply):
- astlist.append(data["rnd"])
-
- try:
- data["donework"] = sum(astlist) / len(astlist)
- except:
- data["donework"] = 0.0
- data["fraction"] = (data["donework"] + data["checklist"]) / 2
-
- # Next section of this data gathering will be about history, scheduling and
- # similar things. I gonna create a dictionary of dates. And input data about
- # those dates into the dates.
-
- # One thing that I have to make sure about is that some dates could be out-
- # side of the range between startdate and deadline. So I have to read the
- # files and add them dynamically.
-
- # Let's start by reading scheduling.
-
- sdata = open(project_location+"/schedule.data")
- sdata = sdata.read()
- sdata = sdata.split("\n")
-
- # Good that schedules already have the right date format. Altho I think of
- # actually using a datetime object as a date. Or is it too much? Let me think
- # I do think loudly. And sinse I have nobody to talk to I will type it here.
- # If you couldn't tell already. Let's write it as a string for now. Because
- # it's easier to work wit strings. Maybe in future I will write it as a
- # datetime object. If i'll find benefit to this.
-
- for date in sdata:
-
- # Let's separate the string into 3 components. Basically scheduling is
- # list of tasks in various checklists through out the project. Example:
-
- # 2020/11/30 /dev/obj/Morias_Bike/asset.progress Rigging=:> Make Bones
- # 2021/05/01 project.progress Marketing=:> Release
-
- # The first entry is a date formatted yyyy/mm/dd. Then comes path of the
- # checklist location. Relative to the project_location. Then a url type
- # thing for with in the checklist. Separating entries with "=:>"
-
- # Also I have to note that in the old Blender-Organizer date 1997/07/30
- # which is my birthday, will make the task be everyday. It will have it's
- # own Green color. Usually when you make a new project there are a list
- # of task created for this date.
-
- if date:
- d = date[:date.find(" ")] # Date
- f = date[date.find(" ")+1:date.replace(" ", ".", 1).find(" ")] # File
- t = date[date.replace(" ", ".", 1).find(" ")+1:].split("=:>") # Task
-
- if d not in data["dates"]:
- data["dates"][d] = {}
-
- # Now in order to decide how to input this data into the data["dates"]
- # we need to look at history at first. Because first of all it has
- # similar syntax. But on the other hand it's a bit more complex.
-
- # 2020/07/05 03:06:34 /dev/chr/Civilian_Child_2/asset.progress Rigging=:> Face Rig=:> Mouth area [V]
- # 2020/07/05 03:06:35 /dev/chr/Civilian_Child_2/asset.progress Rigging=:> Ready to make AST [V]
- # 2020/07/05 03:06:37 /dev/chr/Civilian_Child_2/Civilian_Child_2.blend [Openned]
- # 2020/07/05 03:07:56 /dev/chr/Civilian_Child_2/autolink.data [Updated]
- # 2020/07/05 03:08:08 pln/main.bos [Edited]
- # 2020/07/05 03:08:13 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Openned]
- # 2020/07/05 03:08:25 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Linked]
- # 2020/07/05 03:08:25 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Openned]
-
- # Also history has a feature missing in the schedules. But there is
- # a rub. Scheduling you can rearange by moving them arround. And you
- # can simply move a task to a different day if you so desire.
-
- # In the history apart from the date you also have time up to the second
- # which is a bit more precise in terms of when exactly you made a
- # given task. And I would like scheduling to have the same type of
- # precision. Maybe even introduce a notification system if a certain
- # task is due. But it makes the moving of tasks highly complicated
- # to visualize.
-
- # Maybe a timeline could be a cool idea. Like in the VSE of blender.
- # a place where you could put specific points on a timeline. And time
- # to the next point will be hte length of the part.
-
- # You could move the dots so to change timing of parts. And maybe
- # select them to type in precise values. Could work.
-
-
- # Let's separate the schedule to 3 types. Asset, Scene, Main.
-
- # If it's a scene we are talking about. IK it's a bit shitty. Because
- # I will need to parse this as well. But who cares.
-
- if f.startswith("/rnd"):
- ty = "scenes"
- url = f[:f.rfind("/")].replace("/rnd", "", 1)
- url = url[:url.rfind("/")]
- fn = f.replace("/rnd", "", 1).replace(url, "")
-
-
-
-
- elif f.startswith("/dev"):
- ty = "assets"
- url = f[:f.rfind("/")].replace("/dev", "", 1)
- fn = f.replace("/dev", "", 1).replace(url, "")
-
-
-
- else:
- ty = "files"
- url = ""
- fn = f
-
- if not ty in data["dates"][d]:
- data["dates"][d][ty] = {}
-
- if not url in data["dates"][d][ty]:
- data["dates"][d][ty][url] = []
-
- data["dates"][d][ty][url].append([
- "00:00:00",
- "schedule",
- fn,
- t,
- Username
- ])
-
- # Okay I don't really know what exactly did I just do. But it's seems like
- # a good starting point. Up to a working verion of VCStudio i can edit and
- # change these all I want. Okay I guess it's time to parse another, way
- # harder file. The history. LOL.
-
- # First let's deal with the persantage history file. It's kind of a funny
- # one as well. The funny part is that it has no consistancy at all. I will
- # need to convert it as well. It has a stupid %y-%m-%d format. Which is WTF.
-
- history_percentage_format = "%y-%m-%d"
-
- hdata = open(project_location+"/percentage_hystory.data") # IK spelling LOL
- hdata = hdata.read()
- hdata = hdata.split("\n")
-
- for date in hdata:
- if date.startswith("DATE"):
-
- # An example of the formatting is actually quite amazing. It's going
- # to be realively simple. Example:
-
- # DATE 20-06-26 42.64%
-
- # As you can see it's the word DATE then that date then the fraction
- # as a percantage. Separated by a spacebar.
-
- try:
- t, d, f = date.split(" ")
-
- # Converting the d into a normal date
-
- d = datetime.datetime.strptime(d, history_percentage_format)
- d = datetime.datetime.strftime(d, new_date_format)
-
- # Converting the f into a fraction
-
- f = float(f.replace("%", "")) / 100
-
- except:
- continue
-
- # I just don't want to deal with poeple who are editing the file
- # manually and then say I did something wrong that the program crashed
-
- if d not in data["dates"]:
- data["dates"][d] = {}
-
- data["dates"][d]["fractions"] = {
- "project":f, # The fraction we recieved from the file
- "checklist":0.0, # Place holder for checklist fraction
- "chr":0.0, # \
- "veh":0.0, # |
- "loc":0.0, # > - Plaseholders for categories
- "obj":0.0, # |
- "rnd":0.0 # /
- }
-
-
- # Okay this file was parsed. Which was relativelly simple. NOW. Let's
- # do something a bit harder. Or is it as simple as the other? IDK
- # History file. Example was a bit earlier.
-
- hdata = open(project_location+"/history.data")
- hdata = hdata.read()
- hdata = hdata.split("\n")
-
- for line in hdata:
-
- if not line:
- continue
-
- # So basically every line is quite simple from the left side. But becomes
- # quite complex on the right side. So let's get the left side things
-
- date = line[:line.find(" ")]
- time = line[line.find(" ")+1:line.replace(" ", ".", 1).find(" ")]
- path = line[line.replace(" ", ".", 1).find(" ")+1:line.replace(" ", ".", 2).find(" ")]
- done = line[line.replace(" ", ".", 2).find(" ")+1:]
-
- # I made a mistake allowing paths to have spaces in them. And I need to
- # make sure we have the whole path and not only up to a point.
-
- while done[0] != "[" and ".progress" not in path and "[" in done:
-
- transporting = done[:done.find(" ")]
-
- path = path+" "+transporting
- done = done.replace(transporting+" ", "")
-
-
- # "date" will be our standard date. yyyy/mm/dd. Then "time" is out time
- # from the current day. 24 hours system. hh:mm:ss. "path" is the file to
- # which the change was done. We will need to parse this one. Because it
- # contains the full path to let's say a blend file. While we want to
- # know which asset for example was accessed. Then "done" is the rest of
- # the string. Basically it tells what was actually done with a given file.
- # We will need to parse this one as well somehow. And it scares me a lot
-
- # One thing that we can use it for is restoring the old scheduling list.
- # Becuase in lazy attempt to make user know that a given task is finished
- # I would just delete the task from the schedule file entirely. But
- # in the history file you can find instances of [scheduled] with the full
- # path of a task and the date to which it was scheduled. So yeah.
-
- # Let's get to work.
-
- f = path # Copied from previous
-
- if f.startswith("/rnd"):
- ty = "scenes"
- url = f[:f.rfind("/")].replace("/rnd", "", 1)
- url = url[:url.rfind("/")]
- fn = f.replace("/rnd", "", 1).replace(url, "")
-
-
- elif f.startswith("/dev"):
- ty = "assets"
- url = f[:f.rfind("/")].replace("/dev", "", 1)
- fn = f.replace("/dev", "", 1).replace(url, "")
-
- elif f.startswith("/ast") and ".blend" in f:
- ty = "assets"
- url = f[:f.rfind(".")].replace("/ast", "", 1)
- fn = "[asset_blend]"
-
- else:
- ty = "files"
- url = ""
- fn = f
-
- # Now in order to parse the "done" variable. We need to define functions
- # that we are not looking for. Simple (Trivial) Operations.
-
- simple_operations = [
- "[Edited]",
- "[Openned]",
- "[Linked]",
- "[Edited]",
- "[Updated]",
- "[Added]",
- "[Added Asset]"
- ]
-
- # Basically if "done" in on that list. It's something to do with
- # checklists. And then we have either [V], [ ] or [Scheduled]
-
- if done not in simple_operations:
- if "[Scheduled]" in done:
-
- # These are the missing scheduling data I was talking about.
- # Let's parse this data from the back. The one on the back
- # should be the DATE. Then spacebar. Then the [Scheduled] then
- # another spacebar then the task.
-
- missingdate = done[done.rfind(" ")+1:]
- missingtask = done[:done.rfind(" [Scheduled]")].split("=:>")
-
- # Let's add them into the data. I don't what it will be. Let's
- # see.
-
-
- if not missingdate in data["dates"]:
- data["dates"][missingdate] = {}
-
- if not ty in data["dates"][missingdate]:
- data["dates"][missingdate][ty] = {}
-
- if not url in data["dates"][missingdate][ty]:
- data["dates"][missingdate][ty][url] = []
-
- data["dates"][missingdate][ty][url].append([
- "00:00:00",
- "schedule",
- fn,
- missingtask,
- Username
- ])
-
- # Or else it's a checklist whether been checked or unchecked
-
- else:
- if "[V]" in done:
- done = done.replace(" [V]", "").split("=:>")
- check = "[Checked]"
- else:
- done = done.replace(" [ ]", "").split("=:>")
- check = "[Un-Checked]"
-
- # Putting the thing into the data
-
- if not date in data["dates"]:
- data["dates"][date] = {}
-
- if not ty in data["dates"][date]:
- data["dates"][date][ty] = {}
-
- if not url in data["dates"][date][ty]:
- data["dates"][date][ty][url] = []
-
- data["dates"][date][ty][url].append([
- time,
- "history",
- fn,
- check,
- done,
- Username
- ])
-
- #print(data["dates"][date][ty][url])
-
- # Now let's add all the others.
-
- else:
- if not date in data["dates"]:
- data["dates"][date] = {}
-
- if not ty in data["dates"][date]:
- data["dates"][date][ty] = {}
-
- if not url in data["dates"][date][ty]:
- data["dates"][date][ty][url] = []
-
- data["dates"][date][ty][url].append([
- time,
- "history",
- fn,
- done,
- Username
- ])
-
- #print(ty, url, fn, done)
-
-
-
- #for i in sorted(data["dates"]):
- # print(i)
- # print()
- # print(data["dates"][i])
- # print()
- # print()
-
- #data_save(project_location, data)
-
- return data
- def save(project, data):
-
- # This file will save analitycs data.
-
- try:
- os.mkdir(project+'/set/')
- except:
- pass
-
- with open(project+'/set/analytics.json', 'w') as fp:
- json.dump(data, fp, sort_keys=True, indent=4)
-
-
- def load(project_location):
-
- # This is a simple load analytics funtion.
- name_tmp = project_location[project_location.rfind("/")+1:]
-
- data = {
- "name" : name_tmp, # Name of the project (typed properly)
- "director" : "", # Name of the project's director.
- "status" : "", # Projects's comment / type
- "donework" : 0.0, # Percentage of Assets and Scenes done
- "fraction" : 0.0, # Project's completion percentage
- "checklist" : 0.0, # Project's main checklist percentage
- "startdate" : "0000/00/00", # Date of the start of the project
- "deadline" : "0000/00/00", # Date when project's deadline is
- "duration" : 0, # Amount in days between startdate and deadline
- "timepassed" : 0.0, # Percentage of how much time had passed
- "dayspassed" : 0, # Amount of days since the startdate
- "chr_factor" : 1, # Importance factor for Characters
- "needed" : 0, # Needed % to do today
- "star" : 0, # Did you get needed
- "veh_factor" : 1, # Importance factor for Vehicles
- "loc_factor" : 1, # Importance factor for Locations
- "obj_factor" : 1, # Importance factor for Objects (Other)
- "rnd_factor" : 4, # Importance factor for Scenes (Renders)
- "chr" : 0.0, # Percentage of Characters done
- "veh" : 0.0, # Percentage of Vehicles done
- "loc" : 0.0, # Percentage of Locations done
- "obj" : 0.0, # Percentage of Objects (Other) done
- "rnd" : 0.0, # Percentage of Scenes (Renders) done
- "dates" : {} # Per date, detailed data about the project
- }
-
- try:
- with open(project_location+'/set/analytics.json') as json_file:
- data = json.load(json_file)
- except:
- pass
-
- try:
- projectdata = checklist.get_list(project_location+"/set/project.progress")
- data["checklist"] = projectdata["fraction"]
- except:
- make = open(project_location+"/set/project.progress", "w")
- make.write("[ ] Story\n")
- make.write("[ ] "+talk.text("chr")+"\n")
- make.write("[ ] "+talk.text("veh")+"\n")
- make.write("[ ] "+talk.text("loc")+"\n")
- make.write("[ ] "+talk.text("obj")+"\n")
- make.write("[ ] Animation\n")
- make.write("[ ] Rendering")
- make.close()
-
- # Let's see if dates are fine. Or if they are even dates.
-
- new_date_format = "%Y/%m/%d"
- if not ifdate(data["startdate"]) or not ifdate(data["deadline"]):
- data["startdate"] = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
- data["deadline"] = datetime.datetime.strftime(datetime.datetime.today()+datetime.timedelta(days=30), new_date_format)
-
-
-
- # So we've go the dates. Let's calculate time perventage I guess.
-
- startdate = datetime.datetime.strptime(data["startdate"], new_date_format)
- deadline = datetime.datetime.strptime(data["deadline"] , new_date_format)
-
- delta = deadline - startdate
- data["duration"] = int(delta.days)
-
- delta = datetime.datetime.today() - startdate
- data["dayspassed"] = int(delta.days)
-
- data["timepassed"] = data["dayspassed"] / data["duration"]
- if data["timepassed"] > 1.0:
- data["timepassed"] = 1.0
-
- # LET's FILTER THE SCHEDULES
-
- data["dates"] = schedule.filter(project_location, data["dates"])
-
-
-
- # NEXT THING. As I love to type it into place where people read me while I'm
- # working. We've got data from 2 files. Now we need to get data from ALL the
- # project.
-
- # First we going to get data about the assets. Because it's relativelly easy
- # compared to the story. For which you need to parce a crazy complicated .bos
- # file. Which is a complex database in it's own right.
-
- # So let's go and quickly get data about the assets.
-
- asstfols = ["chr", "veh", "loc", "obj"]
- astlist = []
-
- for n , f in enumerate(asstfols):
-
- flist = []
-
- if len(os.listdir(project_location+"/dev/"+f)) > 0:
- for asset in os.listdir(project_location+"/dev/"+f):
-
- if asset+".blend" in os.listdir(project_location+"/ast/"+f):
- flist.append(1.0)
-
- else:
- try:
- fcheck = checklist.get_list(project_location+"/dev/"+f+"/"+asset+"/asset.progress")
- flist.append(fcheck["fraction"])
- except:
- flist.append(0.0)
-
- # The multiplication thing that I was talking about earlier.
-
- multiply = data[f+"_factor"]
- for m in range(multiply):
- astlist.append(sum(flist)/len(flist))
-
- data[f] = sum(flist)/len(flist)
-
-
- # For the next step I need to have the story parsed and read. But it's going
- # to be so hard. That I will need to write a separate function for it.
-
- data["rnd"] = story.load(project_location)["fraction"]
-
- # After all of it we need to get the final project percentage.
- multiply = data["rnd_factor"]
- for m in range(multiply):
- astlist.append(data["rnd"])
-
- try:
- data["donework"] = sum(astlist) / len(astlist)
- except:
- data["donework"] = 0.0
- # I decided to remove the main checklist from the main fraction. This way the fraction
- # reflects better the overall project. I will keep the old code in a comment for a while.
- data["fraction"] = data["donework"] #(data["donework"] + data["checklist"]) / 2
-
-
- # Let's record it for today.
- today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
- if today not in data["dates"]:
- data["dates"][today] = {}
- data["dates"][today]["fractions"] = {
- "project":data["fraction"],
- "checklist":data["checklist"],
- "chr":data["chr"],
- "veh":data["veh"],
- "loc":data["loc"],
- "obj":data["obj"],
- "rnd":data["rnd"]
- }
-
-
- # Needed
- try:
- alldates = list(reversed(data["dates"].keys()))
- prevdate = alldates[alldates.index(today)+1]
- prev_frac = data["dates"][prevdate].get("fractions", {}).get("project", data["fraction"])
- data["needed"] = ( 1 - prev_frac ) / (( data["duration"] - data["dayspassed"] )/7*data.get("days_a_week", 7))
- except:
- data["needed"] = 0
- prev_star = data.get("star", 0)
- try:
- alldates = list(reversed(data["dates"].keys()))
- prevdate = alldates[alldates.index(today)+1]
- prev_frac = data["dates"][prevdate].get("fractions", {}).get("project", data["fraction"])
- data["star"] = (data["fraction"] - prev_frac) / data["needed"]
- except:
- data["star"] = 0
-
- if data["star"] >= 2 and not prev_star >= 2:
- talk.alert("⭐ Today's Requirement is Finished!")
-
- return data
|