#9 Making it work on Windows

Closed
opened 5 years ago by Zykino · 15 comments
Zykino commented 5 years ago

Hi,

I am trying to use your script on Windows7 (cmd is a pain in ...).
There are some new user easy to fix issues that I fixed locally (I will do a Merge Request after my first successfull upload).

And then there is this issue that... I don't know where it's coming from (I don't know Python)

C:\Users\[Path\To\Prismedia]>"C:\Program Files\Python27\python.exe" prismedia_upload.py --file="[Path\To\Video]" --nfo="[Path\To\nfo]"
2018-08-29 22:41:11,157 Using [Path\To\nfo] as NFO, loading...
Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code[...]
ttps%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.upload[...]
2018-08-29 22:41:43,124 "GET /?state=[...] HTTP/1.1" 200 65
2018-08-29 22:41:43,832 URL being requested: GET https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest
Traceback (most recent call last):
  File "prismedia_upload.py", line 229, in <module>
    yt_upload.run(options)
  File "C:\Users\[Path\To\Prismedia]/lib\yt_upload.py", line 199, in run
    initialize_upload(youtube, options)
  File "C:\Users\[Path\To\Prismedia]/lib\yt_upload.py", line 128, in initialize_upload
    media_body=MediaFileUpload(path, chunksize=-1, resumable=True)
  File "C:\Program Files\Python27\lib\site-packages\googleapiclient\discovery.py", line 788, in method
    actual_path_params, actual_query_params, body_value)
  File "C:\Program Files\Python27\lib\site-packages\googleapiclient\model.py", line 151, in request
    body_value = self.serialize(body_value)
  File "C:\Program Files\Python27\lib\site-packages\googleapiclient\model.py", line 260, in serialize
    return json.dumps(body_value)
  File "C:\Program Files\Python27\lib\json\__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "C:\Program Files\Python27\lib\json\encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\Python27\lib\json\encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc9 in position 0: invalid continuation byte

So an encoding problem but... which file should I check?

Hi, I am trying to use your script on Windows7 (cmd is a pain in ...). There are some new user easy to fix issues that I fixed locally (I will do a Merge Request after my first successfull upload). And then there is this issue that... I don't know where it's coming from (I don't know Python) ``` C:\Users\[Path\To\Prismedia]>"C:\Program Files\Python27\python.exe" prismedia_upload.py --file="[Path\To\Video]" --nfo="[Path\To\nfo]" 2018-08-29 22:41:11,157 Using [Path\To\nfo] as NFO, loading... Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code[...] ttps%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.upload[...] 2018-08-29 22:41:43,124 "GET /?state=[...] HTTP/1.1" 200 65 2018-08-29 22:41:43,832 URL being requested: GET https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest Traceback (most recent call last): File "prismedia_upload.py", line 229, in <module> yt_upload.run(options) File "C:\Users\[Path\To\Prismedia]/lib\yt_upload.py", line 199, in run initialize_upload(youtube, options) File "C:\Users\[Path\To\Prismedia]/lib\yt_upload.py", line 128, in initialize_upload media_body=MediaFileUpload(path, chunksize=-1, resumable=True) File "C:\Program Files\Python27\lib\site-packages\googleapiclient\discovery.py", line 788, in method actual_path_params, actual_query_params, body_value) File "C:\Program Files\Python27\lib\site-packages\googleapiclient\model.py", line 151, in request body_value = self.serialize(body_value) File "C:\Program Files\Python27\lib\site-packages\googleapiclient\model.py", line 260, in serialize return json.dumps(body_value) File "C:\Program Files\Python27\lib\json\__init__.py", line 244, in dumps return _default_encoder.encode(obj) File "C:\Program Files\Python27\lib\json\encoder.py", line 207, in encode chunks = self.iterencode(o, _one_shot=True) File "C:\Program Files\Python27\lib\json\encoder.py", line 270, in iterencode return _iterencode(o, 0) UnicodeDecodeError: 'utf8' codec can't decode byte 0xc9 in position 0: invalid continuation byte ``` So an encoding problem but... which file should I check?
Poster
Owner

Hello!

The first message about the link is the google authentication. Usually, you click on the link, it opens in your web browser to google, and then you allow the apps to use your google account.

Once you have allowed the account, it calls back the apps and it should create the youtube_credentials file.

Cloud you tell me when the error occurs? Do you have the time to click on the link, and it's the callback that crash?
Or did it crash even before clicking?

This part is managed by google lib itself, it could be hard to debug but I am confident we'll do it ;-)

Could you also please tell me what python version you use?

Thanks!

Hello! The first message about the link is the google authentication. Usually, you click on the link, it opens in your web browser to google, and then you allow the apps to use your google account. Once you have allowed the account, it calls back the apps and it should create the youtube_credentials file. Cloud you tell me when the error occurs? Do you have the time to click on the link, and it's the callback that crash? Or did it crash even before clicking? This part is managed by google lib itself, it could be hard to debug but I am confident we'll do it ;-) Could you also please tell me what python version you use? Thanks!
LecygneNoir added the
bug
label 5 years ago
LecygneNoir added the
More info needed
label 5 years ago
Zykino commented 5 years ago
Poster

Yeah forgot to tell when it occurs :s

I setted my own Youtube API keys.
Then launched the script, got the Google page, and accepted the app. Then I saw the message that everything is done with OAuth2 and I can close the page.

The error message was at that moment.
If I relaunch Prismedia I just have the error in the terminal (no page for OAuth).

Yeah forgot to tell when it occurs :s I setted my own Youtube API keys. Then launched the script, got the Google page, and accepted the app. Then I saw the message that everything is done with OAuth2 and I can close the page. The error message was at that moment. If I relaunch Prismedia I just have the error in the terminal (no page for OAuth).
LecygneNoir removed the
More info needed
label 5 years ago
Poster
Owner

Ok, thank you for the details!

It seems the Oauth works good, but the problem occurs when preparing the http request for the API (should remember to add a try/except here).

Unfortunately the error is quite cryptic and comes from the google library :-/

I think it could be related to the windows thing, as windows always had problem with utf8, but I do not know where a utf8 character could come from...

Do you have some special characters in your NFO, or video names? Such as è, é, à, ç and so on.

I advice trying to print the body variable before the insert_request = youtube.videos().insert( part of the code in yt_upload.py (around line 125), and see if python is able to deals with it, or if it raise another utf8 error.

Ok, thank you for the details! It seems the Oauth works good, but the problem occurs when preparing the http request for the API (should remember to add a try/except here). Unfortunately the error is quite cryptic and comes from the google library :-/ I think it could be related to the windows thing, as windows always had problem with utf8, but I do not know where a utf8 character could come from... Do you have some special characters in your NFO, or video names? Such as è, é, à, ç and so on. I advice trying to print the body variable before the `insert_request = youtube.videos().insert(` part of the code in yt_upload.py (around line 125), and see if python is able to deals with it, or if it raise another utf8 error.
Zykino commented 5 years ago
Poster

Installer used for Python: python-2.7.15.amd64.msi

Youtube

By removing the accents from my file, and erasing the description and title it uploaded on youtube.

# Body not working (YT)
{'snippet': {'defaultAudioLanguage': 'fr', 'tags': ['Graveyard Keeper', ' RPG'], 'categoryId': '20', 'description': "En rentrant du travail une voiture nous renverse. Un homme habill\xc3\xa9 en mafieux avec un \xc5\x93il rouge brillant nous dit que nous sommes un gardien de cimeti\xc3\xa8re. O\xc3\xb9 suis-je vraiment ? En quelle ann\xc3\xa9e ? Comment retrouver ma bien aim\xc3\xa9e ?\nSi ce jeu vous int\xc3\xa9resse, vous pouvez l'acheter en [utilisant mon lien partenaire sur Humble Bundle](https://www.humblebundle.com/store/graveyard-keeper?partner=zykino&charity=137859).", 'title': '3 - Am\xe9lioration du cimeti\xe8re'}, 'status': {'privacyStatus': 'public', 'license': 'creativeCommon'}}

# Body working (YT)
{'snippet': {'defaultAudioLanguage': 'fr', 'tags': ['Graveyard Keeper', ' RPG'], 'categoryId': '20', 'description': 'default description', 'title': 'Episode3'}, 'status': {'privacyStatus': 'public', 'license': 'creativeCommon'}}

I am seeing that the "é" chars are transformed into "\xe9" when it is from the command line (title) and into "\xc3\xa9" from the nfo file. Nodepad++ tell me the nfo file use utf-8 encoding with linux style linebreak (LF).

I suppose the Windows 7 cmd use latin-1 instead of utf-8. (If I can believe an old post on developpez.net.)

Peertube

Peertube on the other side, upload and then return a 400 error.
For the Peertube upload I have no clues. Maybe I can log a bit more. Or the infos are on the server log ? (I'm using your instance Pair 2 Jeux)

2018-09-02 13:23:04,839 Peertube: Uploading video...
2018-09-02 13:28:01,180 Peertube: The upload failed with an unexpected response: <Response [400]>
Installer used for Python: python-2.7.15.amd64.msi # Youtube By removing the accents from my file, and erasing the description and title it uploaded on youtube. ``` # Body not working (YT) {'snippet': {'defaultAudioLanguage': 'fr', 'tags': ['Graveyard Keeper', ' RPG'], 'categoryId': '20', 'description': "En rentrant du travail une voiture nous renverse. Un homme habill\xc3\xa9 en mafieux avec un \xc5\x93il rouge brillant nous dit que nous sommes un gardien de cimeti\xc3\xa8re. O\xc3\xb9 suis-je vraiment ? En quelle ann\xc3\xa9e ? Comment retrouver ma bien aim\xc3\xa9e ?\nSi ce jeu vous int\xc3\xa9resse, vous pouvez l'acheter en [utilisant mon lien partenaire sur Humble Bundle](https://www.humblebundle.com/store/graveyard-keeper?partner=zykino&charity=137859).", 'title': '3 - Am\xe9lioration du cimeti\xe8re'}, 'status': {'privacyStatus': 'public', 'license': 'creativeCommon'}} # Body working (YT) {'snippet': {'defaultAudioLanguage': 'fr', 'tags': ['Graveyard Keeper', ' RPG'], 'categoryId': '20', 'description': 'default description', 'title': 'Episode3'}, 'status': {'privacyStatus': 'public', 'license': 'creativeCommon'}} ``` I am seeing that the "é" chars are transformed into "\xe9" when it is from the command line (title) and into "\xc3\xa9" from the nfo file. Nodepad++ tell me the nfo file use utf-8 encoding with linux style linebreak (LF). I suppose the Windows 7 cmd use latin-1 instead of utf-8. (If I can believe [an old post on developpez.net](https://www.developpez.net/forums/d1109556/autres-langages/python-zope/general-python/e-xe9/).) # Peertube Peertube on the other side, upload and then return a 400 error. For the Peertube upload I have no clues. Maybe I can log a bit more. Or the infos are on the server log ? (I'm using your instance [Pair 2 Jeux](https://videos.lecygnenoir.info)) ``` 2018-09-02 13:23:04,839 Peertube: Uploading video... 2018-09-02 13:28:01,180 Peertube: The upload failed with an unexpected response: <Response [400]> ```
Poster
Owner

Ok it's a good news for Windows! I have no problem until then to upload videos event with specials chars, but I always use an ext4 fs as relay to upload my files, I guess this is why I missed this one...

I'll search if there are some compatibility libraries to check chars and convert before uploading as a bugfix :-)

About Peertube, it's even more odd. Indeed usually, when peertube gets a 400, it send it once the video begins to upload, and log the empty or incorrect fields that causes it.
In your case, it waits for 5 minutes before crashing, and in addition to that, nothing more than the error 400 appears inside the server logs :-/

My best guess at the moment is at exactly the same time, Peertube gets 400 errors from mastopeek (a remote tool aiming to check all activity pub instances health), so perhaps the mastopeek requests break something... Or it could be my instance taking a little longer to answer multiples queries, hard to say.

Could you please try reupload only to peertube (using --platform="peertube" in the command line) to see if it fails again?

Thanks!

Ok it's a good news for Windows! I have no problem until then to upload videos event with specials chars, but I always use an ext4 fs as relay to upload my files, I guess this is why I missed this one... I'll search if there are some compatibility libraries to check chars and convert before uploading as a bugfix :-) About Peertube, it's even more odd. Indeed usually, when peertube gets a 400, it send it once the video begins to upload, and log the empty or incorrect fields that causes it. In your case, it waits for 5 minutes before crashing, and in addition to that, nothing more than the error 400 appears inside the server logs :-/ My best guess at the moment is at exactly the same time, Peertube gets 400 errors from mastopeek (a remote tool aiming to check all activity pub instances health), so perhaps the mastopeek requests break something... Or it could be my instance taking a little longer to answer multiples queries, hard to say. Could you please try reupload only to peertube (using --platform="peertube" in the command line) to see if it fails again? Thanks!
Zykino commented 5 years ago
Poster

I uploaded the video from the interface without problem.
Testing right now with the next video (and accents in desc (nfo) and title (cmd)).

Failed in the exact same way.

I uploaded the video from the interface without problem. Testing right now with the next video (and accents in desc (nfo) and title (cmd)). Failed in the exact same way.
Poster
Owner

Thank you, this time I get it!

If I am right, you tried an upload through the web interface around 14h12, and it's successful.

Then a new one with the script around 16h45, and this one failed.

I get in the log some chars problem indeed : 4 - Test avec des accents ���� for the prismedia test.

What's odd is this appear when inserting the video into the BDD, so I think all parameters for the upload are OK, but once the upload is terminated and peertube try to add it to the BDD, there it fails.

It explains why you have the 400 not immediately after beginning the upload.

I am unsure if this is a bug in peertube, or something wrong with my BDD settings refusing some sort of chars. As the log displays the I tend to think about some problem when peertube check for not allowed char before inserting in BDD.

Is this possible for you to try to print in the prismedia code the variables multipart_data and headers in the file pt_upload.py just before upload, around line 123? Just before the response = oauth.post(url + "/api/v1/videos/upload", part.

Alternatively, you could tell me what chars were used where the in the video name?

Is the name created from the file's name, or do you specify it in the NFO?

Thanks !

Thank you, this time I get it! If I am right, you tried an upload through the web interface around 14h12, and it's successful. Then a new one with the script around 16h45, and this one failed. I get in the log some chars problem indeed : `4 - Test avec des accents ����` for the prismedia test. What's odd is this appear when inserting the video into the BDD, so I think all parameters for the upload are OK, but once the upload is terminated and peertube try to add it to the BDD, there it fails. It explains why you have the 400 not immediately after beginning the upload. I am unsure if this is a bug in peertube, or something wrong with my BDD settings refusing some sort of chars. As the log displays the `�` I tend to think about some problem when peertube check for not allowed char before inserting in BDD. Is this possible for you to try to print in the prismedia code the variables `multipart_data` and `headers` in the file `pt_upload.py` just before upload, around line 123? Just before the `response = oauth.post(url + "/api/v1/videos/upload",` part. Alternatively, you could tell me what chars were used where the `�` in the video name? Is the name created from the file's name, or do you specify it in the NFO? Thanks !
Zykino commented 5 years ago
Poster

Are we ok that it's not the authentication which fail ?
My peertube secret file contains a whole lot of specials characters in the password (and nothing is between quotes)

PS: Editing my comment doesn't work and the number of messages are not updates on gitea ? Look strange.

Are we ok that it's not the authentication which fail ? My peertube secret file contains a whole lot of specials characters in the password (and nothing is between quotes) PS: Editing my comment doesn't work and the number of messages are not updates on gitea ? Look strange.
Poster
Owner

Yep it's not the authentication, if it was it should breaks at the very start of the upload, as we generate a token using the auth before trying to upload, and according to the log the token is OK.

I have myself a complex password and it works smoothly (with %, # and other é and {). You should not use quote inside the conf file, as it will be interpreted as a character in the password. However, if you could, I guess trying to change the password could not hurt (there is an old bug about pseudo not using case sensitive, it could be something like that for password)

PS: Yes I have noticed the gitea messages number problem, I have an upgrade late, perhaps it would solved it. But I was able to edit my comments thought :-/

Yep it's not the authentication, if it was it should breaks at the very start of the upload, as we generate a token using the auth before trying to upload, and according to the log the token is OK. I have myself a complex password and it works smoothly (with %, # and other é and {). You should not use quote inside the conf file, as it will be interpreted as a character in the password. However, if you could, I guess trying to change the password could not hurt (there is an old bug about pseudo not using case sensitive, it could be something like that for password) PS: Yes I have noticed the gitea messages number problem, I have an upgrade late, perhaps it would solved it. But I was able to edit my comments thought :-/
Zykino commented 5 years ago
Poster
prismedia_upload.py --file="Episode4.mp4" --nfo="nfo.txt" --platform="peertube" --privacy=private --name="4 - Test avec des accents éèàù"
2018-09-02 17:29:35,313 Using nfo.txt as NFO, loading...
2018-09-02 17:29:36,605 Peertube: Uploading video...
multipart_data
<MultipartEncoder: [('name', '4 - Test avec des accents \xe9\xe8\xe0\xf9'), ('licence', '1'), ('description', "En rentrant du travail une voiture nous renverse. Un homme habill\xc3\xa9 en mafieux avec un \xc5\x93il rouge brillant nous dit que nous sommes un gardien de cimeti\xc3\xa8re. O\xc3\xb9 suis-je vraiment ? En quelle ann\xc3\xa9e ? Comment retrouver ma bien aim\xc3\xa9e ?\nSi ce jeu vous int\xc3\xa9resse, vous pouvez l'acheter en [utilisant mon lien partenaire sur Humble Bundle](https://www.humblebundle.com/store/graveyard-keeper?partner=zykino&charity=137859)."), ('nsfw', '0'), ('channelId', '103'), ('videofile', ('Episode4.mp4', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.mp4", mode 'rb' at 0x00000000039739C0>, 'video/mp4')), ('tags', 'GraveyardKeeper'), ('tags', 'RPG'), ('category', '7'), ('language', 'fr'), ('privacy', '3'), ('commentsEnabled', '1'), ('thumbnailfile', ('Episode4.jpg', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.jpg", mode 'rb' at 0x0000000003973660>, 'image/jpeg')), ('previewfile', ('Episode4.jpg', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.jpg", mode 'rb' at 0x0000000003973810>, 'image/jpeg'))]>
headers
{'Content-Type': 'multipart/form-data; boundary=00303c3b341d4c749c82ef3483f84865'}
``` prismedia_upload.py --file="Episode4.mp4" --nfo="nfo.txt" --platform="peertube" --privacy=private --name="4 - Test avec des accents éèàù" 2018-09-02 17:29:35,313 Using nfo.txt as NFO, loading... 2018-09-02 17:29:36,605 Peertube: Uploading video... multipart_data <MultipartEncoder: [('name', '4 - Test avec des accents \xe9\xe8\xe0\xf9'), ('licence', '1'), ('description', "En rentrant du travail une voiture nous renverse. Un homme habill\xc3\xa9 en mafieux avec un \xc5\x93il rouge brillant nous dit que nous sommes un gardien de cimeti\xc3\xa8re. O\xc3\xb9 suis-je vraiment ? En quelle ann\xc3\xa9e ? Comment retrouver ma bien aim\xc3\xa9e ?\nSi ce jeu vous int\xc3\xa9resse, vous pouvez l'acheter en [utilisant mon lien partenaire sur Humble Bundle](https://www.humblebundle.com/store/graveyard-keeper?partner=zykino&charity=137859)."), ('nsfw', '0'), ('channelId', '103'), ('videofile', ('Episode4.mp4', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.mp4", mode 'rb' at 0x00000000039739C0>, 'video/mp4')), ('tags', 'GraveyardKeeper'), ('tags', 'RPG'), ('category', '7'), ('language', 'fr'), ('privacy', '3'), ('commentsEnabled', '1'), ('thumbnailfile', ('Episode4.jpg', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.jpg", mode 'rb' at 0x0000000003973660>, 'image/jpeg')), ('previewfile', ('Episode4.jpg', <open file "D:\\Documents\\Videos Let's Play\\GraveyardKeeper\\Episode4.jpg", mode 'rb' at 0x0000000003973810>, 'image/jpeg'))]> headers {'Content-Type': 'multipart/form-data; boundary=00303c3b341d4c749c82ef3483f84865'} ```
Poster
Owner

Wow this is weird, exact same error in log, but the description has its special chars without problem Oo

If you tried to upload, but just removing special char in the name, and letting them in the description?

Wow this is weird, exact same error in log, but the description has its special chars without problem Oo If you tried to upload, but just removing special char in the name, and letting them in the description?
Zykino commented 5 years ago
Poster

Done.

Done.
Poster
Owner

Hello,

To answer question from the Peertube dev on Peertube issue regarding this problem, we need to get the full http answer from the server.

Could you please tyring to display the full http error when uploading, by modifying the pt_upload.py file, around line 128 :

else:
            logging.error(('Peertube : The upload failed with an unexpected response: '
                           '%s') % response)
            exit(1)

to

else:
            print(response.json())
            logging.error(('Peertube : The upload failed with an unexpected response: '
                           '%s') % response)
            exit(1)

Thanks!

Hello, To answer question from the Peertube dev on [Peertube issue](https://github.com/Chocobozzz/PeerTube/issues/1024) regarding this problem, we need to get the full http answer from the server. Could you please tyring to display the full http error when uploading, by modifying the `pt_upload.py` file, around line 128 : ``` else: logging.error(('Peertube : The upload failed with an unexpected response: ' '%s') % response) exit(1) ``` to ``` else: print(response.json()) logging.error(('Peertube : The upload failed with an unexpected response: ' '%s') % response) exit(1) ``` Thanks!
Zykino commented 5 years ago
Poster

{u'error': u'Unknown video video channel for this account.'}

`{u'error': u'Unknown video video channel for this account.'}`
Zykino commented 5 years ago
Poster

Look like it worked \o/

2018-09-07 22:27:03,690 Peertube: Uploading video...
RESPONSE
{u'video': {u'id': 6459, u'uuid': u'29e590e4-f27a-4518-abe2-b5abbbe6d19c'}}
2018-09-07 22:31:16,242 Peertube : Video was successfully uploaded.
2018-09-07 22:31:16,242 Peertube: Watch it at https://videos.lecygnenoir.info/videos/watch/29e590e4-f27a-4518-abe2-b5abbbe6d19c.

I propose you that I send a PR for Peertube (and the channel/playlist selection) to close this issue. And we open an other issue for the accents.

For the record :

  1. I hard-coded the channel's ID to test ASAP
  2. No problems with accentuation in the description (from a UTF-8 nfo file)
  3. Non ASCII chars in title were replaced by "�" (é, è, à and ç)
Look like it worked \o/ ``` 2018-09-07 22:27:03,690 Peertube: Uploading video... RESPONSE {u'video': {u'id': 6459, u'uuid': u'29e590e4-f27a-4518-abe2-b5abbbe6d19c'}} 2018-09-07 22:31:16,242 Peertube : Video was successfully uploaded. 2018-09-07 22:31:16,242 Peertube: Watch it at https://videos.lecygnenoir.info/videos/watch/29e590e4-f27a-4518-abe2-b5abbbe6d19c. ``` I propose you that I send a PR for Peertube (and the channel/playlist selection) to close this issue. And we open an other issue for the accents. For the record : 1. I hard-coded the channel's ID to test ASAP 1. No problems with accentuation in the description (from a UTF-8 nfo file) 1. Non ASCII chars in title were replaced by "�" (é, è, à and ç)
Zykino closed this issue 5 years ago
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.