Giter VIP home page Giter VIP logo

django-robo-cjk's People

Contributors

blackfoundry avatar fabiocaccamo avatar justvanrossum avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-robo-cjk's Issues

automatic lock on glyph creation

When we create a glyph with

atomic_element_create
deep_component_create
character_glyph_create

it automatically lock the glyph for the designer.
But then when the designer want to open the glyph to edit it, RoboCJK relock it again. So RoboCJK see twice a lock and avoid modification.s

I think we should remove the automatic lock of these three creation function. But does this will affect you @justvanrossum or not?

[logging] Send email notification in case of error.

The standard django email logger sends an email for each logger.error call, this is good but could end up in sending hundreds of emails per hour in some scenarios, especially when there is an error during the export.

To avoid receiving multiple emails for the same kind of error in a short time interval we need to add a custom logger.

Glyph and layer names can not contain chars > BMP

If I try to create a layer name that contains a non-BMP char (unicode > U+FFFF, say "𠃓", U+200D3, or "👀", U+1F440), the server throws an error:

HTTPError('500 Internal Server Error - (1267, "Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb3_general_ci,COERCIBLE) for operation \'=\'")')

The same happens when using such a char in a glyph name.

As far as I can see, this is coming from MySQL.

Not high priority, and, like the long layers names, I could work around this in Fontra, but it's probably good to know.

font_update(): not possible to set empty fontlib, features or designspace

In the font_update() function, the if xxx: conditionals will evaluate to false for empty values, and will then not update the field. This makes it impossible to clear any of those fields.

I can't find the definition for get_dict(), so I don't know what it returns for a missing argument. There should be a distinction between "argument not given" and "argument is empty".

def font_update(request, params, user, font, *args, **kwargs):
font_changed = False
# look for fontlib data
fontlib = params.get_dict("fontlib")
if fontlib:
font.fontlib = fontlib
font_changed = True
features = params.get_str("features")
if features:
font.features = features
font_changed = True
designspace = params.get_dict("designspace")
if designspace:
font.designspace = designspace
font_changed = True
# font is changed, save it
if font_changed:
font.save_by(user)
return ApiResponseSuccess(font.serialize())

Layer name length limit of 50 characters is very low

We definitely need may want to raise the limit, but I'm thinking whether we can come up with a scheme that lifts the limitation completely.

We could shorten long layer names for storage by truncating them and appending a hash. This is easy if we only need to map from "long layer name" to "shortened layer name".

Alternatively, we can work around this in the rcjk Fontra backend, and do the mapping there.

Another "status" field bug when uploading glif data without status

Traceback (most recent call last):
  File "/root/robocjk/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/root/robocjk/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/root/robocjk/lib/python3.8/site-packages/sentry_sdk/integrations/django/views.py", line 67, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
  File "/root/robocjk/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/root/robocjk/lib/python3.8/site-packages/django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 42, in wrapper
    raise internal_error
  File "/root/robocjk/src/robocjk/api/decorators.py", line 39, in wrapper
    response = view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 90, in wrapper
    return view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 153, in wrapper
    return view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 436, in inner
    return view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 77, in inner
    return view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/decorators.py", line 202, in wrapper
    return view_func(request, *args, **kwargs)
  File "/root/robocjk/src/robocjk/api/views.py", line 616, in character_glyph_update
    character_glyph.save_by(user)
  File "/root/robocjk/src/robocjk/abstract_models/core/timestamp.py", line 58, in save_by
    self.save()
  File "/root/robocjk/src/robocjk/models.py", line 997, in save
    self._update_status(glif_data)
  File "/root/robocjk/src/robocjk/models.py", line 943, in _update_status
    if init_val == 4 and val < init_val:

Exception Type: TypeError at /api/character-glyph/update/
Exception Value: '<' not supported between instances of 'NoneType' and 'int'

It is val which is None here.

Feature request (for Fontra): add web API to return "modified since" glyph IDs for a font

Relates to #13. With a call like that, Fontra can poll, say once per minute, so it can let clients know glyphs have been changed in the meantime.

It would be good for me if this call would bundle all changed CG's, DC's and AE's into a single response (a list per type).

The response should only contain glyph IDs, not glyph data. Fontra will request fresh data if needed, but it is expected that this is often a subset of the set of actual changes.

I imagine the call to be defined something like this:

    def glyphs_modified_since_list(self, font_uid, timestamp):
        ....

And the return value to be something like this:

{"ae": [1, 2, 3], "dc": [5, 6, 7], "cg": [9, 10, 12]}

[export] Improve delta check before rasing exception.

The objective is to avoid invalid errors like:

Expected 0, found 35 atomic elements .glif files on file-system.

To avoid that these kind of invalid exceptions will be raised 2 changes are necessary:

  • Raise exception only if the expected glif files count > 0
  • Change delta tolerance of expected glif files to 0 <= n <= 50

Feature request: an option for xxx_lock and xxx_unlock to not return any glif data

This is about

  • character_glyph_lock / character_glyph_unlock
  • deep_component_lock / deep_component_unlock
  • atomic_element_lock / atomic_element_unlock

I do like the fact that unlock also returns the updated_at and layers_updated_at fields, but the glif data is redunant for my use case, as I will only lock after I've long downloaded the relevant glyph data.

[git export] Zombie Files

Glyphs that are deleted from the DB only get deleted once a day, instead of immediately upon export.

This is currently blocking a release of GS CJK.

Glyph locking should ideally not be done by user ID

Currently, if a user owns the lock for a glyph, the same user can ask for the lock again, even from another client. This also implies: user A on client B can unlock the lock owned by user A on client A (as the client ID is not taking into account).

A practical scenario where this will cause problems (or at least confusion):

  • User A opens a glyph in RoboCJK.
  • RoboCJK locks the glyph on behalf of user A
  • User A opens a glyph in Fontra
  • User A edits the glyph in Fontra
  • Since user A owns the lock, Fontra will succeed with:
    • getting the lock
    • updating the glyph
    • unlocking the glyph
  • Now the glyph is unlocked, even for RoboCJK, but RoboCJK doesn't know that: it still thinks it holds the lock
  • Next up: confusion and/or errors and/or lost edits

This is expected to be a rare thing, given our path forward with Fontra, and we need to decide carefully whether it is worth fixing at this point.

(Note that the plan is for Fontra to have its own locking layer, which will will indirectly prevent this problem from being one if all edits are done via Fontra.)

A possible solution for this is:

  1. Disallow locking an already locked glyph even by the same user
  2. The response to a succeeded lock call should contain an “unlock key” (a random token made by the server)
  3. Unlocking requires passing the unlock key

Multiple glyph encodings not included in in glif_list response

A glyph can have multiple code points, so that any of those code points will be mapped to that glyph in the final font.

The data currently returned by glif_list only contains the first of such code points in the response, in the unicode_hex field.

Fontra needs to be able to construct a complete cmap from the glif_list output, so it needs all the code points associated with each glyph.

(In .glif data, the <unicode> element can appear multiple times.)

(An example of a multiple-encoded glyph is uni313B in GS CJK Hangul.)

[api] Add server time to all API responses.

Or: how does a client know what timestamp to use when requested updated_since glyph lists?

Should responses perhaps contain the current time (timestamp of the response), according to the server?

Or should there be an additional api for "current time on the server"?

Glyph names should be case sensitive, but they are not

It is currently not possible to create a glyph with the name a when a glyph A already exists.

Error:

400 Bad Request - Character Glyph with font_uid='263d7da5-16c0-4a2f-b5bb-763a1b082d6b' and name='a' already exists.

('a' does not in fact exist, but 'A' does.)

Some files have not been included in the incremental export.

Some files have not been included in the incremental export, then after having modified them they have been included in the next export.

The cause of this issue is probably related to the glif creation date VS the project/font export start date.

Using requests.Session() is a good speedup

Using a Session, api calls take up to half the time compared to without using a Session. Probably mostly because of the reuse of the connection.

--- robocjk/api/client.py	2021-12-09 21:37:40.000000000 +0100
+++ /Users/just/code/git/fontra/vault/client.py	2021-12-09 21:34:18.000000000 +0100
@@ -56,6 +56,8 @@
         if not password:
             raise ValueError('Invalid password: {}'.format(password))
 
+        self.session = requests.Session()
+
         # strip last slash in case
         if host.endswith('/'):
             host = host[:-1]
@@ -107,7 +109,7 @@
             # 'verify': self._host.startswith('https://'),
         }
         # send post request
-        response = requests.post(url, **options)
+        response = self.session.post(url, **options)
         if response.status_code == 401:
             # unauthorized - request a new auth token
             self.auth_token()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.